Viewing By Category : orm / Main
February 4, 2010

This year's cf.Objective() is offering SIX pre-conference classes! You can choose from Building Secure CFML Applications, ColdBox: 100 Training, Developing Applications with ColdFusion 9 ORM, Getting Started with Flex / AIR Development, Mach-II / OOP from the Ground Up, Rapid Development with Model-Glue 3! Wow!

Some of these are one-day courses (Wednesday April 21st) and some are two-day courses (Tuesday April 20th and Wednesday April 21st).


May 11, 2009
In the absence of a printable schedule - sorry, Joe Rinehart says it's a problem with the Media3 hosting and he's been trying to get them to fix it for months! - here is my schedule for cf.Objective() 2009:

[More]


April 25, 2009
Now that Adobe has provided most of their session titles, we had to move Jason Delmore's Object Relational Mapping session to earlier in the schedule (so Terry Ryan's Advanced ORM session could follow).

That means that if you signed up for Jason's talk, you're now signed up for Terry's advanced talk and if you signed up for Adobe's "super secret" Friday talk at 1:45pm, you're now signed up for Jason's basic ORM talk!

Feel free to visit the online scheduler to update your selections if necessary!


March 14, 2009
Some people - myself included - have observed runaway memory usage and apparent memory leaks with applications built with certain combinations of CFML frameworks that include Transfer ORM. We spent a lot of time tuning the JVM and looking at code and database usage in our Broadchoice Community Platform (CMS), we worked with Mike Brunt on load testing and tuning (highly recommended - if you have any performance problems, get Mike on your case!) as well as working with Mark Mandel directly on Transfer itself. All that work led to a much more stable system and we decided to just continue investigating as a background task.

[More]


December 23, 2008
Liz has announced the first round of topics for CFUNITED 2009. It's an interesting mix of speakers - some old, some new - and a broad spectrum of subject matter.

After CFUNITED 2008, Liz has promised lots of changes and improvements and we already know that the venue is something special and an all-in-one location (addressing a bit complaint about the last few years' conferences). One of the new changes for 2009 is that a quarter of the content will be Flex/AIR related, acknowledging the growth and increasing relevance of these technologies to ColdFusion developers at large.

Some of the highlights (from my point of view) of the topics announced so far:

  • Flex development with the Swiz framework - Chris Scott
  • Railo Open Source - Gert Franz
  • Groovy for ColdFusion Developers - Joe Rinehart
  • iPhone Apps + Adobe ColdFusion - Josh Adams
  • ColdFusion, Model-Glue, Hibernate, Spring, and Groovy - Ray Camden
  • AIR: Building Desktop Applications with Flex 3 - Rob Rusher
  • Hack Proofing ColdFusion - Shlomy Gantz

Definitely not your father's CFUNITED!


September 7, 2008
I'm already used to the magic that is Transfer and I can't imagine building a ColdFusion application without it. Adobe have said they're looking at integrating Hibernate into "Centaur" and showed some simple examples of how it might work in their keynote at CFUNITED (I expect we'll see more at MAX - you are going to MAX, right?). Hibernate is the de facto standard ORM for the Java world and it is very robust, scalable and feature-rich.

We've been using Hibernate for a while to manage the persistence of our business objects and that has driven us toward Groovy for those business objects since, right now, you cannot use Hibernate with ColdFusion Components in any meaningful way and we didn't want to write all the verbose code that Java would require.

A recent discussion on the Transfer mailing list has focused on how to model one-to-one relationships and why Transfer doesn't support them directly. This is one area in which Hibernate's features go far beyond what Transfer offers - and part of the reason for us to "switch" to Hibernate for future product development.

Another modeling quandary when it comes to persistence is how to handle inheritance.

[More]


August 15, 2008
We have a live system with customer data and a new requirement comes along that a particular piece of customer data must be encrypted in the database from now on. We already encrypt some columns (using Triple DES - which you might have guessed given the recent posts on my blog and here about mimicking ColdFusion's encryption in Java/Groovy). What is the smallest possible code change to ensure that as any user updates their data in future, this item will automatically be encrypted - whilst still handling the case of legacy data being unencrypted?

We use Transfer for all our persistent business objects and almost all of our business objects have a decorator defined (for validation or some additional business logic). We also use Brian's TDOBeanInjectorObserver to automatically inject services into our business objects - just add a setter for a service and the bean injector takes care of the rest.

Here's the bean injector definition in our ColdSpring file:

<bean id="transferObjectInjector" class="coldspring.transfer.TDOBeanInjectorObserver">
   <constructor-arg name="transfer"><ref bean="transfer" /></constructor-arg>
   <constructor-arg name="suffixList"><value>service,datasource</value></constructor-arg>
   <constructor-arg name="debugMode"><value>true</value></constructor-arg>
</bean>
Normally you would declare it non-lazy but we already do other non-lazy initialization so in our ColdSpring factory initialization code, we do this:
<cfset bf.getBean("transferObjectInjector") />
to force the bean injector to be initialized which, in turn, registers itself as a Transfer event listener (so that it can intercept object creation). The suffixList specifies that any set*Service() method or set*Datasource() method on the business objects managed by Transfer should be matched to beans defined in ColdSpring and injected.

So how do we add the on-demand encryption to our business object's data?

[More]


July 15, 2008
Update: Bob just added Part VII so I'm updating this post to include that.
For ease of reference I just wanted to post a quick note highlighting Bob Silverberg's excellent series on using Transfer ORM and OO architecture: If Bob adds additional pieces, I'll update this post with his new articles.

There's a lot of good information here although it may be a bit overwhelming on first read so be prepared to keep coming back to these posts!


May 28, 2008
May has been a quiet month on the blog because it has been an extremely busy month at Broadchoice. We completed our 2.0.2 and 2.0.3 releases and launched the new platform with a fair bit of press coverage.

The platform is powered by ColdFusion 8.0.1, running Model-Glue 2 (BER), ColdSpring 1.2 BER and Transfer 1.0 BER and runs on a cluster of 64-bit Linux servers with synchronization of the Transfer cache managed through a set of ActiveMQ JMS server instances. The database is MySQL.

We're continuing to work on a stream of minor releases as well as planning our next major release with a lot of new features.

I'll be pulling together some presentations and articles about how we're using the frameworks together (because I think we're doing some interesting and unusual things, behind the scenes). I'll some a few snippets of code at Scotch in both of my presentations (and again at CFUNITED). I'm talking to the CFDevcon organizers about appropriate topics and they suggested a framework-related session so that might be the first unveiling of some of our ColdSpring / Transfer tricks and tips. I expect Ray will also be blogging about some aspects of our application architecture in due course.

Feel free to sign up for a free Broadchoice account and see what we've been up to! Our support site (also powered by the Broadchoice Web Platform, as is our public website - we like to eat our own dog food!) has several ways for you to provide feedback to us!


May 19, 2008
Mark has just announce the second Release Candidate build of Transfer ORM 1.0. He's been holding back on this until Broadchoice confirmed that a particularly stack overflow error in the cache discard was fixed. We confirmed that today for him, after extensive testing - both human and automated.

As many of you know - especially those who attended cf.Objective() - we hired Alagad to have Mike Brunt perform extensive load testing on our system, built with Model-Glue 2, ColdSpring and Transfer. One of the issues he found was a memory leak and Mark worked tirelessly with us prior to, throughout and after cf.Objective() to track it down and fix it. Mike helped us tune and debug our systems and I look forward to having him back to help us when we move to the next stage with our servers (as we investigate additional instances and more JVM tuning).

So download and test Transfer 1.0 RC 2 and report any issues you find to Mark so that he can fix them in time for the 1.0 release at WebDU!


May 9, 2008
Kay Smoljak is running a series of interviews with framework developers and has a summary article on SitePoint that includes a survey of people's framework usage. It's going to be a great series of articles and makes interesting reading (FarCry and COOP have been covered so far with Fusebox, Mach-II, Transfer and ColdBox coming soon - and Model-Glue and ColdSpring et al to follow). The survey will only be open for a few more days so rush over and make your voice heard!


April 26, 2008
Mark Mandel just published the release notes for the upcoming 1.0 Release Candidate of Transfer. You can see just how busy he's been lately. The 1.0 RC should be available any day now - in time for cf.Objective() 2008 where Mark will give an introduction to developing applications using Transfer as well as an advanced talk on the caching machinery in Transfer.


April 14, 2008
If you use Mark Mandel's awesome Transfer ORM in a cluster, you've probably wondered what to do about keeping the cache in sync across servers in the cluster. I've had to solve this problem a couple of times now and I figured I should publish an example of how to do this.

[More]


April 12, 2008
That's a question that crops up over and over again. I've blogged about it in the past. My answer - as I'm sure most folks would expect - is "it depends". The question came up on a mailing list again the other day and someone jumped in full of praise for ColdBox and then someone else said "Sean would say it depends" and went on to plug cf.Objective() as the "perfect place" to answer the question, wishing they could be there.

Here's what I said in response:

[More]


March 28, 2008
No fair! No fair! Brian Rinaldi leaks the upcoming Transfer 1.0 release along with the ColdBox-powered documentation wiki.

Transfer continues to evolve at a rapid pace. The SVN repository is light years ahead of the last "official" release (0.6.3) and 1.0 is "coming soon". Mark Mandel deserves huge kudos for his work on this project - and his intent to turn this into "Professional Open Source". In other words, making Transfer something we can rely on like we rely on JBoss or MySQL today.

Come to cf.Objective() 2008 to hear Mark talk in person about Transfer in two great sessions!


January 14, 2008
Brian Kotek has released his Transfer decorator bean injector observer which I'm very excited about because I just needed this functionality for a client's project and had to write a version myself. Brian's is more sophisticated and, hopefully, will be integrated into ColdSpring in due course. Now I can use his version instead of mine and know that I'm using a community-supported resource.

I know Brian Ghidinelli also ran into this issue and had started to write his own as well. I expect he'll switch to Brian Kotek's version now.

So what does it do? Well, as you build complex domain objects by writing decorators for Transfer objects, you find you need access to services that you are managing with ColdSpring. Transfer provides an event model so you can add a listener (observer) for the afterNew event and use that to inject dependencies into your domain objects. It's a fairly manual process. What Brian's CFC does is completely automate the process. You declare the injector in your ColdSpring file and pass in Transfer to its constructor. When ColdSpring initializes the injector, the injector registers itself as an observer for that event and then it automatically injects any matching services, based on setters in the decorator. Very slick!


November 13, 2007
Today I discovered an unpleasant aspect of working with Reactor and ColdSpring: if your database and code don't match and you have ColdSpring creating gateways or DAOs using Reactor as a factory bean, you can get the very helpful "Fatal Error" and nothing else.

The exception from Reactor - about the database mismatch - is swallowed by ColdSpring and reported as a bean initialization exception. If that in turn is caught and dealt with by the application's initialization code, you no longer have any indication of what the problem might be.

Fortunately, we have a great tool at our disposal to dig into these buried exceptions: the ColdFusion 8 debugger!

I fired up the debugger in Eclipse and enabled break on CFML exceptions and write exceptions to the Eclipse log. As expected with ColdSpring and its exception-happy nature, I hit a few false starts but then I hit the Reactor exceptions. There are a couple of harmless exceptions as it tests for some optional plugin points but then you get the real exception, showing up in the Eclipse log. Very convenient!


October 31, 2007
Mark Mandel is running an Advanced Transfer Workshop via cfFrameworks on November 28th. I saw his Advanced Transfer presentation at cf.Objective() 2007 and it was a great session. If you're on the fence about persistence frameworks, or you've just started using Transfer and want to know what it's really capable of, you need to tune into this presentation!


July 1, 2007
After the networking event, Joe Rinehart hosted a Birds of a Feather session on frameworks. He covered the new release of Model-Glue 2.0 for ColdFusion, the Alpha 1 release of Model-Glue for Flex (which looks very exciting!) and said that Model-Glue for Java, developed by Chris Scott (I think) would also become an official Model-Glue project - all on the new Model-Glue website.

Next up I covered the Fusebox 5.5 release which is currently in limited Alpha with a public Beta planned in July (as soon as we can get enough documentation together on the new features). I also announced publicly that providing a migration path for Fusebox 3 was on the roadmap (for Fusebox 5.7 probably).

Matt Woodward (and Peter Farrell) presented Mach II 1.5 which is in Beta right now, and the new website. He also talked about plans for their 2.0 release (but didn't go into specifics).

Next up was Chris Scott, who said that an official 1.2 release would appear within a few weeks and then they would be working toward a 1.5 release. This will be the last release of ColdSpring that will run on CFMX 7 - ColdSpring 2.0 will require CF8 because they want to take advantage of cfinterface and onMissingMethod() to make ColdSpring faster (and simplify the core files).

Last up was Doug Hughes who assured us that Reactor would hit an official 1.0 release as soon as the documentation was complete. Ah, the dreaded documentation...


May 21, 2007
Brian Kotek has an excellent post about using ColdSpring to its full potential, in response to a series of articles on Tom Chiverton's blog about building services with ColdSpring and Reactor.

Brian shows how to use the factory-bean and factory-method descriptors in your ColdSpring XML file to handle automatic injection of beans obtained from factory objects that are also managed by ColdSpring. It's a powerful technique that helps completely remove a number of dependencies from your application code.

I use the same technique with Transfer and ColdSpring:

<bean id="dataSource" factory-bean="transferFactory" factory-method="getDatasource" />

<bean id="transfer" factory-bean="transferFactory" factory-method="getTransfer" />
This allows me to inject the data source object and the main Transfer API object directly into my service layer objects so they don't have to know about the Transfer factory at all.


April 18, 2007
Lots of people like Ruby on Rails for the speed with which you can build web applications. One of the tradeoffs I often bring up in discussions of abstraction - which Rails offers in spades! - is that each layer of abstraction adds a certain amount of overhead. Sometimes it's easy to refactor the abstractions out in order to reduce overhead (and improve performance). Sometimes it's hard.

Andrew Shebanow has a good post about this tradeoff in relation to Twitter, which is powered by Ruby on Rails. Alex Payne, of Twitter, has talked about their experience with the massive scalability explosion that the site has seen and some of the "friction" that they've encountered trying to refactor the abstractions out.

I worry about this in the context of most every framework I use - and there's certainly been plenty of noise on mailing lists and blogs over the years about the performance of frameworks. One of the reasons I've settled on Fusebox for the Scazu website is that it compiles all the circuit files down to inline CFML on the first request so the abstraction is compiled out (this is one of the core messages in my "Extending the language of Fusebox" presentation - see slides and sample code under 'SOFTWARE' on my blog).

I've also been a fan of Transfer for ORM, lately because of the TQL - Transfer Query Language - component that lets me write complex database queries using an object / property abstraction. It looks much like SQL but lets you use the terminology of your application instead of the terminology of the database. It does add overhead but refactoring methods that use TQL into methods that use the underlying raw SQL is pretty straightforward and can be done on a method by method basis (and, in fact, I recently refactored one performance-critical method in exactly this way).

Going back to Andrew's post (and the underlying comments from Alex), I'd say that Transfer has a low friction coefficient that contributes to why I like it so much.


April 17, 2007
It's official: Transfer 0.6.3 Goes Final says Mark Mandel. Not much has changed since the Release Candidate but now it is an official build. Mark will be at cf.Objective() 2007, telling folks all about Transfer and how to build applications with it - in two different sessions!


March 31, 2007
Well, we want a good user experience designer / user interface developer and a good ColdFusion developer.

For the first role, we want someone who can create crisp, clean user interfaces that are intuitive and easy to use. You'll have good graphic design skills and the ability to take a UI vision and turn it into lightweight HTML + CSS, with slick JavaScript for interactivity. If you've got ColdFusion skills, that's a bonus.

For the second role, we want someone who can build high-performance, highly scalable ColdFusion systems. You'll have a good grasp of application frameworks and object-oriented development (preferably Fusebox + ColdSpring + Transfer since that's what we use - but experience with otherwise frameworks and a willingness to learn will count).

For both roles, you will be able to work independently (and remotely, if appropriate) but with a focus on delivery and collaboration. Familiarity with source code control (e.g., SVN) and bug tracking software (e.g., Trac) is a requirement.

It's early days for Scazu so we're looking for folks who can be creative about compensation in exchange for a stake in the company. Our collective success will mean you'll be in at the ground level and able to build your own teams over time so it's a great opportunity for the right folks!


March 27, 2007
Mark Mandel, creator of the Transfer ORM system, is flying in from Australia to speak at cf.Objective(). Judith Dinowitz has interviewed Mark for Fusion Authority and it's well-worth reading.


March 21, 2007
Following up on Matt Newby's comment on my recent post about Transfer, here's a bullet point comparison of Transfer and Reactor that I hope will help people who are looking at ORMs and trying to decide which one to use:

Reactor:

  • Reactor implements the Active Record pattern, with objects knowing how to handle their own persistence.
  • Reactor provides a rich OO-style query expression mechanism (you construct queries as OO data structures, then have Reactor execute them).
  • Reactor can deduce the basic structure of your database tables for you - you only need XML to describe relationships or to alias columns and tables.
  • Reactor generates "record" objects, gateways and metadata.
  • To customize a Reactor object, you extend the generated object (and Reactor does not overwrite it).
  • Reactor does not provide caching.

Transfer:

  • Transfer focuses on business objects and provides a data access layer - you ask Transfer to load an object, you ask Transfer to save an object.
  • Transfer provides a SQL-like abstraction, called TQL (Transfer Query Language), that makes handling queries of related objects really easy.
  • Transfer does not introspect the database - you need to specify all of the table structure and relationships in XML, but you can also organize those object mappings into packages and have plenty of control over how the relationships are represented in the object model.
  • Transfer builds your business objects on the fly, rather than laying down CFCs for you.
  • To customize a Transfer object, you can either write CFML functions directly in the XML (and Transfer will include those when it generates the business objects on the fly) or you can write a "decorator" object to wrap any Transfer-managed business object.
  • Transfer provides a sophisticated caching layer.


Mark Mandel has been working hard on Transfer in preparation for webDU 2007 and somehow managed to ship Transfer 0.6.3 RC1 before he flew out today.

The two key new features in 0.6.3 are:

  • afterNew listener hook so you can inject dependencies into newly created TransferObjects
  • TQL - Transfer Query Language, modeled on Hibernate's HQL
I haven't used the former but I can see how it would be very, very useful in certain situations. The latter, however, has become my favorite Transfer feature overnight! I'm building out a site that uses Fusebox 5 + ColdSpring + Transfer and TQL is a major feature of the model right now. What has really impressed me is the performance: with cache evaluation enabled the overhead is so low that the benefits of the abstraction is completely worth it!


March 2, 2007
Nic Tunney just announced some of the new features in objectBreeze 2.0 which he is actively working on. Looks like a lot of work is going into this next release. Glad to see named getters/setters coming disappointed to see collections go away - that was one of the interesting USPs about objectBreeze. It'll be interesting to see how Nic's iterator approach works out in place of collections.


February 25, 2007
Jared has posted a partial session list for the upcoming cf.Objective() conference. I'm speaking twice on related topics. I'll be talking about the work my team has been doing in the Adobe Hosted Services group, explaining our architecture - based on ColdSpring and Transfer - as well as looking at one particular area that has caused us a lot of pain: error handling.

You'll learn how we built the back end that supports several functions behind Acrobat Connect and Adobe Document Center - and Kuler - as well as some of our pain points and, in particular, the problems that arise when dealing with error handling around the boundaries of systems in a Service-Oriented Architecture.


February 8, 2007
Update: this proxy is not needed to have a single instance of the Transfer factory shared between multiple Model-Glue applications. You can simply have an alias tag in each application that references the single transferFactory object in the parent factory:
<alias name="transferFactory" alias="ormService"/>
So why did I think this wouldn't work?

I created a test case for parent / child bean factories and aliases, I put nothing but aliases in the child factories. ColdSpring couldn't find the aliases. I deduced (wrongly) that ColdSpring did not allow aliases in child factories to redefine beans in the parent factory.

Silly me. Turns out that my test case uncovered a bug in ColdSpring: aliases only work if the factory contains at least one real bean. At least, that's what my test cases seem to show. I'm going to run this past the ColdSpring crew for confirmation.


Want to share a single instance of Transfer between multiple Model-Glue applications?

Original code / post edited out.

The definition of transferFactory is in your parent bean factory which you tell Model-Glue about by putting this line in your index.cfm:

<cfset ModelGlue_PARENT_BEAN_FACTORY = application.cs />
(assuming your overall Application.cfc is creating application.cs).

All the Model-Glue apps share that Application.cfc and so they all have the same parent bean factory which contains the single instance of the Transfer factory object. Each Model-Glue app has its own proxy object that delegates an alias that refers to the single factory object.


February 5, 2007
I just committed the assertions plugin I wrote en route to the Frameworks Conference. You can view the source in the repository or download it via SVN.

The code needs some cleanup but I figured it might be nice to get this out in front of people to get some feedback. This will eventually be the solution to ticket 25 as part of Fusebox 6.

Also in the repository are the Reactor and Transfer ORM lexicons that I showed at the Frameworks Conference. Again, these need code cleanup and enhancement but they should be a good starting point for people wanting to use either ORM library with Fusebox. A more comprehensive Reactor lexicon is also available.


February 4, 2007
My Frameworks Conference talk is now available as a download from the "Software" pod on my blog - both the PDF of the slides and the ZIP of the code.

The code includes:

  • The ORM lexicons which provide identical syntax for accessing both Reactor and Transfer within your circuit.xml file.
  • The Cat Club task manager variant that is, essentially, the Model-Glue version (ggcc7) implemented as a Fusebox 5 lexicon.
  • The simplified task manager application that uses the ORM lexicons.
  • The new and as yet unannounced assertions lexicon / plugin that implements preconditions, postconditions and invariants.
I'll write more about the assertions machinery in due course. Let me know if you have any questions about the other code in the ZIP file.


January 27, 2007
Mark Mandel released Transfer 0.6.1 while I was away in Montana so I'm a bit late to the party with this news.

In addition to the documentation enhancements I mentioned earlier, the official 0.6.1 release includes improvements to the caching engine and a variety of bug fixes and performance enhancements. It also removes the earlier Model-Glue integration files because support for Transfer has now been added directly into Model-Glue itself.


January 10, 2007
I noticed that Mark Mandel has been updating the documentation for Transfer in response to feedback from the community. It now contains a Getting Started section as well as expanding the section on caching. If you have feedback on the documentation you should either join the transfer-dev mailing list and post it there (sign up link on the main Transfer page) or log a bug via the RIAForge site for Transfer.


January 9, 2007
The very latest Model-Glue: Unity (the SVN trunk) now has direct support for Transfer built in.

Joe mentioned that he has moved the explicit Reactor ORM support declarations out of the core Configuration.xml file. In that post he said you could just declare the ormAdapter and ormService beans directly yourself.

His code base has moved on (already). If you download the very latest from SVN and you have the very latest ColdSpring from CVS, then you can take advantage of the new <alias> tag in ColdSpring!

In your Model-Glue application's ColdSpring.xml file, just add these two lines to use Transfer:

<alias name="ormService.Transfer" alias="ormService"/>
<alias name="ormAdapter.Transfer" alias="ormAdapter"/>
Or, to use Reactor, add these lines instead:
<alias name="ormService.Reactor" alias="ormService"/>
<alias name="ormAdapter.Reactor" alias="ormAdapter"/>
MG:U has built-in adapters for both Reactor and Transfer now and default declarations for both ORM's factories (as the ormService.* beans above). Of course, you can easily override any of these if you need (for example, we have the Transfer factory in our parent bean factory and define our ormService to be a proxy to the Transfer factory so that all our MG:U applications share a single factory object).


December 5, 2006
Mark Mandel has officially released version 0.6 of his Transfer ORM. Compared to the earlier RC, it contains some battle-tested bug fixes but is otherwise functionally equivalent. As I noted in an earlier blog post, the incremental version number is deceptive: 0.6 is a huge release after 0.5!

Still concerned about Transfer not being at "1.0" yet? Transfer 0.6 powers some of the machinery behind the recently released Adobe Acrobat Connect and Adobe Document Center services.


November 7, 2006
Brian Rinaldi hosted Mark Mandel presenting on his Transfer ORM library today. It was an excellent introductory presentation. Brian has made the recording available.


November 2, 2006
Brian Rinaldi will be hosting Mark Mandel presenting Transfer ORM. Please RSVP on Brian's blog so he has an idea of numbers.


October 31, 2006
Mark Mandel has released a major update to his Transfer ORM library (don't be fooled by the minor version number change from 0.5 - this is a huge release!).

You can read all about the new features in his blog entry about the new release. If you have any concerns about trying Transfer because it hasn't reached the magic "1.0" release yet, put those concerns aside and try it anyway. My team has been using Transfer happily for a while (and will shortly be launching a new service where the persistence layer is powered by Transfer!).


October 23, 2006
Brian has written up a great tutorial on using the Transfer ORM. He shows how to configure and use Transfer in the context of a Mach II / ColdSpring application he has been building.


Mark Mandel has moved his Transfer ORM project to RIAForge with forums, bug tracker and Subversion repository. The current download is still the 0.5 build but Subversion contains a much more up-to-date version (which we are using at Adobe). You can read Mark's blog at Compound Theory.


September 29, 2006
After Peter Bell stirred the pot, Peter Farrel wrote a fairly explosive post (repeating a lot of what he said on the cfweekly, episode ?) and it spurred Joe Rinehart to respond with an impassioned blog post defending the design choices made in the development of Model-Glue: Unity.

As someone who has contributed extensively to Mach II, Model-Glue, Fusebox, ColdSpring and Reactor (phew!), I would like to step up and defend Joe's decisions - he's done a sterling job, sticking to his vision for the framework and has been very clear about what should be in the framework and what should not. As a framework developer myself, I can tell you it's a rocky road. The "community" deluge you with requests for all sorts of features and you have to stand firm and defend your vision. None of the popular frameworks are "kitchen sink" efforts - there are countless feature requests that have been denied by the framework authors.

I've requested enhancements to all these frameworks. Some of those requests have been implemented but most have been denied. Even as lead developer on one of the Mach II releases, some of my suggested enhancements were turned down (and some of the changed Peter implemented in Mach II were reverted as inappropriate for the framework).

When I built Fusebox 5, I was deliberately very conservative about what went into the framework and what didn't. I implemented a few things the community really wanted that I didn't think were great ideas but I also did not implement several things that I thought were great ideas that the community weren't very interested in.

Fusebox 5.1 will be a fairly conservative enhancement release. Fusebox 6 has more scope for adding features but, even so, backward compatibility will be maintained and the addition of features will be strictly controlled but community-driven.

I don't know how community-driven Mach II is. I don't think it has a public bug tracker (Model-Glue, Fusebox, ColdSpring and Reactor all do). I get the impression that Application.cfc support was added for coolness (the other frameworks have taken great pains to remain compatible with CFMX 6.1 and equivalent competing ColdFusion engines).


September 18, 2006
Now that Mark has added a configuration object to Transfer, it's time to document how you can configure Model-Glue to use Transfer for the ORM integration which drives GDMs (Generic Data Messages) and scaffolding. First off, you need the very latest version of Transfer from CVS (see the transfer.riaforge.org website for details). Second, you need a fairly up-to-date version of Model-Glue (from SVN).

Third, crack open Model-Glue and edit one of the core files - shock! horror! Edit ModelGlue/unity/config/Configuration.xml and change the definitions for ormAdapter and ormService as follows:

<!--
   This defines what ORM service to use, such as Transfer.
-->

<bean id="ormAdapter" class="transfer.modelglue.TransferAdapter">
   <constructor-arg name="framework">
      <ref bean="ModelGlue" />
   </constructor-arg>
</bean>

<!--
   This defines the ORM service
-->

<bean id="ormService" class="transfer.TransferFactory">
   <constructor-arg name="configuration">
      <ref bean="transferConfiguration" />
   
</constructor-arg>
</bean>
The transferConfiguration bean definition will appear either in your Model-Glue's local ColdSpring.xml or a global configuration that is used as the parent bean factory for Model-Glue (see earlier blog posts about this sort of configuration).

Your Transfer configuration might look like this:

<bean id="transferConfiguration" class="transfer.com.config.Configuration">
   <constructor-arg name="datasourcePath">
      <value>/environment/transfer/datasource.xml</value>
   </constructor-arg>
   <constructor-arg name="configPath">
      <value>/environment/transfer/transfer.xml</value>
   </constructor-arg>
   <constructor-arg name="definitionPath">
      <value>/environment/transferdata</value>
   </constructor-arg>
</bean>
That's all there is to it! Model-Glue will now use Transfer for scaffolding and GDMs. Bear in mind this is an early cut of the integration right now. In particular, it doesn't support validation or any form of relationship yet. However, it should be enough to let you do basic table-based operations using Transfer.

Joe and Mark and I are still looking at what it will take to support relationships with Transfer in Model-Glue. To be clear, Transfer has sophisticated support for relationships but Model-Glue's ORM support is very Reactor-centric right now which makes this level of integration somewhat more difficult!


September 16, 2006
My lack of blogging lately is because I've had my head down coding, along with my colleagues Matias and Paul. This week we had several important milestones on our current project so we have been putting the finishing touching to some of our web services (Matias), build system (Paul - learning to love ant) and administrative consoles (me).

I've talked before about the structure of our service-based system: we use ColdSpring to manage all of the model components; we have simple web service / Flash Remoting facades in front of that model; we share that configuration with our Model-Glue applications using the parent bean factory feature of ColdSpring. I've been focusing on the Model-Glue side of the things this week, so I thought I'd blog about how that's working out for us.

[More]


September 13, 2006
Mark Mandel just made me a committer on the Transfer project so I added the first cut of the Model-Glue adapter (and metadata and dictionary objects) to CVS (on transfer.riasforge.org). No documentation yet - we need a separate Transfer configuration object (yeah, like Reactor has) before it becomes easy enough to use to be worth documenting. And I've realized that there are a couple of small enhancements to ColdSpring that will make it easier to swap pluggable adapters inside Model-Glue (already raised on the coldspring-dev list).


September 12, 2006
Mark Mandel just announced on the Transfer mailing list that the latest version in the repository has incorporated my first cut at Model-Glue integration (so that Generic Data Messages and basic scaffoling work with Transfer if you define the ormAdapter and ormService beans appropriately - more detail on this in due course!) as well as cache improvements and some bug fixes.

He also listed some of the enhancements he is planning on adding shortly, including a separate configuration object which will make Model-Glue integration easier.


September 3, 2006
As folks can probably guess from recent posts, I've been taking another look at Mark Mandel's Transfer ORM library over the last few weeks and this weekend I've been looking at what it would take to integrate Transfer with Model-Glue.

Model-Glue has an adapter-based architecture for ORM and ships with an implementation for Reactor. It has an ORM controller that implements the "Generic Data Messages" (e.g., ModelGlue.genericList) and relies on a Reactor-specific adapter for the actual integration with the ORM.

The ReactorORMController that ships with Model-Glue is almost entirely generic because of the adapter interface which is a testament to Joe's great design skills. Because of that, I was able to get a basic Transfer adapter up and running fairly quickly to the point that the GDMs all worked. A bit more work and I was able to get basic scaffolding working too (by creating some basic metadata and a fake dictionary object).

I haven't tackled any of the table-to-table relationship stuff but I wanted to let a broader audience know about this proof of concept to gauge interest...


September 2, 2006
I just went through the PowerPoint slides from Mark Mandel's presentation to the Melbourne CFUG (back in late June). It's a great introduction to his ORM library and shows the depth of functionality available.

Fast forward to today and Mark just committed some changes to CVS that provide a number of documentation improvements as well as the ability to turn off the internal transactions in Transfer's create / update / delete operations so that you can wrap multiple Transfer operations in your own cftransaction tags (just as Reactor allows). He has also recently added a readByPropertyMap() method that allows objects to be read based on a collection of property values (again, much like Reactor's load() method).


August 30, 2006
A lot of buzz and excitement surrounds Doug Hughes' Reactor ORM project (and rightly so) but it isn't the only game in town. As those of you who've seen my talk on OO and persistence (download the preso and code from the "software" pod on my blog, if you haven't), I talk about four ORM frameworks that appeared at roughly the same time: Arf!, objectBreeze, Reactor and Transfer. Arf! was intended to be a quick prototyping tool, inspired by ActiveRecord (from Ruby on Rails) but the other three were aimed at solving production scale problems.

Reactor was the most ambitious and seems to have attracted all the attention. The other two got a bit lost in Reactor's shadow.

I recently started taking a second look at the Transfer ORM library by Mark Mandel and it's really grown up a lot since I last looked at it.

It takes a different approach to Reactor (and Arf!), not relying on the ActiveRecord idiom, but instead assuming intelligent business objects for which Transfer provides persistence. It may seem a subtle difference but it's an important one. A business object does not know how to create / read / update / delete itself - that's the job of Transfer itself - but Transfer provides the infrastructure to create and manage the business objects (as well as persist them). Transfer provides a solid event model (before / after observers for persistence operations) and has recently added full decorator support so you can write easily customizable business object CFCs that are "attached" to a persistable CFC that handles the core business object data.

Transfer also provides very sophisticated caching machinery (which I haven't fully gotten into yet).

Installation is clean and straightforward. Although Java code is used, no special attention needs to be paid to the JAR it needs because Transfer has its own class loader built in to take care of the JAR. Very slick!

It also seems to be a very low overhead ORM, in terms of raw performance.

Currently supports SQL Server, MySQL, Oracle and PostgreSQL but the approach it takes is much more generic than Reactor so adding additional databasess should be very easy. It doesn't use database introspection so there's less "magic" going on (which probably also contributes to the lower overhead in performance).

Definitely worth another look. If you don't like the ActiveRecord style of persistence, Transfer might be just what you're looking for.

Oh, and Mark Mandel created a #transfer IRC channel on DAL.net so if you have questions, pop in and he'll be there (during the Australian day time). I'll be there too.


August 12, 2006
Nathan Strutz has created a couple of Fusebox 5 lexicons that make it easier to use ColdSpring and Reactor with Fusebox 5. Nice work Nathan!


My team is building a lot of web services right now. Although we have a number of discreet groups of services, they share some common infrastructure and they all interact with a common database schema. We decided early on that we would use ColdSpring to manage the model components behind our web services and, as we've been building out the code base, we've settled on what seems to be a nice structure that allows each group of services to be developed fairly independently but still all be wired together as part of one ColdFusion application (so we can share data cached in application scope, for example).

[More]


July 10, 2006
You can now register for MAX 2006. The sessions & tracks are all listed as well. Plenty of ColdFusion sessions this year with a good range of levels. I'll be there as part of a three hour session covering frameworks and methodologies - ColdSpring, Fusebox, Mach II, Model-Glue and Reactor will all be covered. Yes, Fusebox at MAX!


June 25, 2006
Doug Hughes just announced the second candidate build for the upcoming beta release. Doug's goal for the beta is a solid, stable API and reasonable documentation (produced with RoboHelp, donated by Adobe).

Everything's coming together nicely for CFUNITED in terms of framework releases. ColdSpring is at 1.0 RC 1, Reactor is now at 1.0 BC 2, Model-Glue: Unity is in public beta and Fusebox 5 RC 1 will be announced at CFUNITED.


June 10, 2006
Wow! I've been following the development of Model-Glue 2.0 a.k.a. Unity pretty closely but even that hadn't prepared me for just how impressive Joe's video demo would be! In about eight and a half minutes, he builds a blog application (including manually creating the post / comment tables in the database).

From the video, you'll see that Unity uses Reactor to drive the database access and ColdSpring to manage both the Model-Glue service components and the Reactor factory itself. A very powerful combination!


May 26, 2006
A great piece of news from Doug Hughes: Reactor now has a Trac project site and HTTP-based SVN access! This provides access to Reactor's bleeding edge for folks behind firewalls (like me most of the time) as well as a wiki and bugbase and so on, just like I've been using for Fusebox 5.


May 13, 2006
The members of my team, Hosted Services, has a wide variety of backgrounds and experience but, until I joined the team, had not looked at ColdFusion as a viable technology for doing integration work.

The benefits of ColdFusion are slowing becoming apparent to my (formerly non-ColdFusion) colleagues: Java integration is fairly seamless, exposing code through web services or Flash Remoting is almost trivial, high-level tags that simplify integration tasks.

Within my overall team, I run a small group focused on core infrastructure and integration and we're getting into some prototyping work now and for that we're going to use Model-Glue to build quick HTML user interfaces and test harnesses and Reactor to simplify the data access layer, with a view to moving to custom SQL queries for performance later on. Given the ease of using ColdSpring with Model-Glue to manage the service layer, I strongly suspect we'll end up using all three frameworks together for our prototyping.

Over time we'll build out Flex 2 user interfaces, probably even for the internal administrative consoles that we might initially build using Model-Glue. The service layer we build should be directly reusable in that situation.

So far, the initial response to Model-Glue, ColdSpring and Reactor has been positive and we're looking forward to Model-Glue 2.0 a.k.a. "Unity".


April 16, 2006
Jared Rypka-Hauer is maintaining up-to-date versions of the CFC Documentation of these frameworks for the community.


March 17, 2006
Just a reminder that I will be speaking at the Denver CFUG this Monday. "Objects & Persistence" will be the topic, covering object / relational mapping and Reactor (amongst other persistence frameworks).


March 16, 2006
I meant to blog this last week: Nic Tunney's objectBreeze persistence framework just hit 1.0 with the addition of support for Oracle and PostgreSQL.


March 14, 2006
I just added my two talks and the persistence sample application to the software pod on my blog.


March 7, 2006
As an example of how to hook these together, here are two bean definitions (from the ColdSpring XML config file) that show how to have ColdSpring create and inject a Reactor gateway into your Model-Glue controllers:
<bean id="reactorFactory" class="reactor.reactorFactory">
      <constructor-arg name="configuration">
         <value>/ggcc10/config/reactor.xml</value>
      </constructor-arg>
   </bean>
   
   <bean id="taskGateway" factory-bean="reactorFactory"
      factory-method="createGateway">

      <constructor-arg name="objectAlias">
         <value>task</value>
      </constructor-arg>
   </bean>
Kurt Wiersma recently updated ColdSpring so you can define a factory and specify that other beans are obtained from that factory instead of directly from ColdSpring.

In the ModelGlue.xml file, specify the ColdSpring loader and that you want autowiring:

<setting name="beanFactoryLoader"
         value="ModelGlue.Core.ColdSpringLoader" />

       <setting name="autowireControllers" value="true" />
Finally the controller has a setter for the task gateway:
<cffunction name="setTaskGateway" returntype="void" access="public" output="false">
      <cfargument name="gw" required="true" />
      
      <cfset variables.taskGateway = arguments.gw />
      
   </cffunction>
ColdSpring will create the Reactor factory bean and then use it to create the task gateway and will then inject it into the controller for you.

Magic!


Model-Glue, ColdSpring and Reactor have all been updated in their repositories to handle the issues that I have talked about over the last couple of days. I'll be packaging up "ggcc10" for release at / after cf.Objective() - the Model-Glue / ColdSpring / Reactor variant of my frameworks comparison sample application.

Reactor is also getting some performance tweaks - some are already in the repository, more will be committed before cf.Objective() (do you see a pattern here?).

Check out the latest "BER" versions to try out the new abilities!


March 5, 2006
As part of the preparation for my talks at cf.Objective() (it's not too late to buy your ticket!), I've been working quite a bit more recently with both ColdSpring (for my factories talk) and Reactor (for my persistence talk).

ColdSpring has recently been enhanced to support factory-bean and factory-method attributes in a bean definition so that you can declare beans that are actually created by external factories such as Reactor.

You declare the Reactor factory as a bean (managed by ColdSpring). Then you can declare DAO and gateway objects, in the ColdSpring XML file, which are created by the Reactory factory bean.

It's very slick.

However, most Reactor operations are focused on record objects which are transient (not singletons) and whilst those could be managed by ColdSpring, generally only singletons - per-application objects like services - should be managed by ColdSpring (since it adds a layer of complexity to object creation in order to leverage the power of the framework).

I was attempting to apply AOP to Reactor-generated objects so that I could simulate the security model in ggcc9 (the ninth variant of my frameworks comparison code - see the software pod on my blog). ColdSpring assumes that AOP-controlled objects are simple concrete classes and therefore it doesn't work with the nested inheritance hierarchy of the Reactor-generated DAO and gateway objects.

I did eventually make it work but it requires changes to ColdSpring and, for some of the autowiring I was doing, some changes to Model-Glue as well. I've submitted the patches to the revelant mailing lists for consideration but it means that I can't realistically release the ggcc10 variant's source code.

Despite my minor frustrations, the combination of the three frameworks is immensely powerful. If you look at the ggcc9 variant, you'll see it has several model CFCs and several bean CFCs. The ggcc10 variant has none of that. The model was really just DAOs and gateways which Reactor provides automatically and the beans become records which, again, Reactor manages automatically. About a dozen CFCs went away in the conversion. That's a lot of code I wouldn't have to write!


February 27, 2006
Doug Hughes has posted a summary of changes and enhancements to the Reactor ORM framework. He's working toward a 1.0 release and, as you can see, he's certainly very busy working on the framework to create a stable, full-featured release.

He credits me with donating MySQL 4.x support but I should point out it was only partial support and several other Reactor community members have since contributed bug fixes and enhancements for that. Oracle support is also in the works from the Reactor community (but is trickier due to how it handles auto-incrementing primary keys - or rather how it doesn't handle them but relies on sequences etc).


February 17, 2006
Brian covers covers some of the more powerful features of Reactor from a newcomer's perspective. He shows how to manipulate relationships between objects / tables as well as the power of the query object to perform joins etc. It's nice to see coverage of Reactor from the trenches showing what it's really like to build applications with it.


January 20, 2006
Mark talks about his early experiences with Reactor (and the mailing list!) and is very positive about it all. His post shows some of the power of Reactor, using the Query object abstraction to perform joins without needing to write SQL.


Barney relates a discussion he was having with Simeon Bateman and Chris (?) about persistence and talks about a technique he uses to manage generated CFC code (leveraging a source code control system). The comments quickly drift off into ORM framework land which highlights some more of the pros and cons of each approach.


Doug Hughes presented Reactor to the Online ColdFusion Meetup Group. It was an excellent presentation that really only scratched the surface of what Reactor can do for you.

Steven Erat has a good write-up and link to the recording.


January 6, 2006
Doug Hughes has made some fairly significant updates to Reactor including the start of some serious documentation, performance improvements and bigger, better sample applications (including a full-blown, full-featured blog based on Model-Glue and Reactor that uses FCKEditor for composing posts). It also includes MySQL 4.x support contributed by yours truly (since I needed that for my "Objects & Persistence" talk coming soon to a CFUG near you!).

Doug will be presenting Reactor at the Online ColdFusion Meetup Group on January 19th (36 yes, 7 maybe). He'll also be presenting Alagad Image Component and Alagad Captcha the week before, January 12th (32 yes, 7 maybe). RSVP soon!


December 28, 2005
As I just discovered, Arf! won't work if you have columns in your tables with certain names... The Arf! ActiveRecord component defines several getters and setters - you cannot have a column named for any of those properties (because the generated code has getters and setters for those columns which then conflict with the base class methods).

That means you can't have columns called: isbuilt, recordfactory, datasource, tablename, primarykey, relations, term or uilibrary.

I doubt you'll trip over those but I did - I'm building a wiki sample app and had a column called... term. I renamed it to wikiterm and all is well.


December 8, 2005
On January 12 - United ColdFusion Meetup Day! - Doug will talk about the Alagad Image and Captcha components.

On January 19, he will talk about Reactor.

See the Online ColdFusion Meetup Group calendar for more details.


December 7, 2005
Over the weekend I was reading JDJ (yes, I've started getting it again... no, I don't know why I'm back on Sys-Con's list!) and they recently had an "Extreme Makeover: Architecture Edition" feature (October).

The article related Franz Garsombke's experiences refactoring a large, poorly-structured Java application using five iterations. Along the way, explaining the benefits of layered architecture, dependency injection, AOP, mock objects (for testing), DAOs / Hibernate and Spring, he talks about creating a framework for mapping JavaBeans across application layers / interfaces. They made it available as an open source project called Dozer. It's an interesting idea and I can see its applicability in the ColdFusion world as well, especially now we are starting to see the use of dependency injection (ColdSpring) and ORM libraries (like Arf!, Transfer, Reactor, objectBreeze etc).

However, when I went and looked at the documentation, the XML (which describes the mapping between objects) struck me as being pretty ugly (tags called classA, classB, A and B for example). I'd be interested to hear whether anyone has used Dozer and / or whether anyone has created something similar for ColdFusion...


November 14, 2005
I've been playing with Arf! quite a bit lately and I thought I'd share some of the code in my little sample app, just to show how useful Arf! can be for small dynamic applications.

Naturally it's cat-related. I built the On Safari website last year (I am not responsible for the visual design!) using Fusebox and what little dynamic content I needed I was loading into the database from CSV files.

This year I decided to build a small content admin section to make this a more pleasant process as I add more content that people send me about past On Safari shows. For the admin, I decided to use Model-Glue, ColdSpring and Arf!

Code to fetch all the awards and sort them by year and sequence number:

<cfset var award = variable.rf.createRecord("admin.model.cataward") />
<cfset var awardSelect = award.list(orderby="osyear DESC, seq ASC").getQuery() />

<cfset arguments.event.setValue("awards",awardSelect) />

Code to read in a single award record by ID:

<cfset var awardId = arguments.event.getValue("id") />
<cfset var award = variable.rf.createRecord("admin.model.cataward") />

<cfif len(awardId)>
    <cfset award.read(awardId) />
</cfif>
<cfset arguments.event.setValue("award",award) />
I treat the record as a bean later on in the code so I actually reuse this method for both the 'add' and 'edit' scenarios. If the awardId is blank, then I get an empty 'bean' to populate the form - otherwise I get real data (my add and edit forms are the same view).

Code to save an award (either new or edited - Arf! knows that a blank ID means add a new record):

<cfset var fields = "id,osyear,seq,award,donor,donorcattery,cattery1,catname,cattery2,owners" />
      <cfset var award = variable.rf.createRecord("admin.model.cataward") />
<cfset var i = "" />

<cfloop list="#fields#" index="i">
    <cfinvoke component="#award#" method="set#i#">
        <cfinvokeargument name="#i#" value="#arguments.event.getValue(i,'')#" />
    </cfinvoke>
</cfloop>
<cfset award.save() />

<cfset arguments.event.addResult("success") />

And, finally, code to delete an award:

<cfset var awardId = arguments.event.getValue("id") />
<cfset var award = variable.rf.createRecord("admin.model.cataward") />

<cfset award.setId(awardId) />
<cfset award.delete() />

<cfset arguments.event.addResult("success") />

You can decide for yourself how much work this saves. The cataward CFC is essentially empty (just the Arf! template). It was certainly nice not having to write CRUD SQL but in an app this size there wouldn't be very much of it.

It works, it's reasonably fast - certainly fast enough for my little admin needs.

What could I do better? Well, I ought to have a separate DAO layer and isolate the use of Arf! inside that rather than just manipulating Arf! in my controller but I just wanted a quick'n'dirty content admin. I'm only using ColdSpring to create and load the Arf! Datasource and RecordFactory objects (overkill but convenient). I'm using the autowire feature (in the ColdSpring CVS version, not yet released).


November 13, 2005
I don't know about your shared hosting company but the way mine is set up, you need to specify the username / password with every <cfquery> tag (rather than just once in the DSN setup).

For the most part that's fine - I just put the details into a config bean and have all my code read it back out.

Over the last couple of days I've built an Arf! / ColdSpring / Model-Glue application to manage content (actually on cat-related site, not mine) and whilst I had everything working just fine locally (Arf! is pretty slick for simple persistence management), nothing would work correctly on the shared host.

Arf! generates code that assumes the username / password are held in the datasource definition so the first thing I had to change was the <cgquery> tags in the generator (yes, cg, not cf). That still didn't work tho' because Arf! takes advantage of the datasource service in ColdFusion MX to access the database metadata. It turns out that the getConnection() call can be passed the username / password - and that is needed in this case.

So I modified the Datasource.cfc bean to have a username / password and modified the factory code to use those attributes in the getConnection() call.

Then I started to get connection errors. It turns out that with some database systems, you cannot close the connection until after you have finished accessing the metadata. Joe has a comment in his code (for the column metadata) that indicates he'd hit a similar problem. I moved the call to loadTables() into loadDatabaseMetadata() (where the connection is still active) and I moved another call to conn.close() after the last reference to the metadata (where the column metadata is fetched).

Then I discovered the CFC name used to represent the table is case-sensitive on some systems so I renamed my CFCs and edited the code that creates them.

Finally, it all worked. Well, almost. After all that, I'd forgotten that this particular site is hosted on CFMX 6.1 rather than CFMX 7 - so now I need to rewrite my <cfform> tags not to use format="xml". How quickly you get used to new features!

Overall, the Arf! functionality is very useful and saves me writing a lot of tedious SQL. I still have to write tedious data entry forms and marshal data out of the form (event object, in this case) into the 'record', but it definitely saved me some time.


November 1, 2005
The ever-industrious Joe Rinehart has started work on an ActiveRecord-like component for ColdFusion, inspired by Ruby on Rails. The code is not yet available but Joe is interested in your feedback...




Hosting provided by