An Architect's View

CFML, Clojure, Software Design, Frameworks and more...

An Architect's View

Comparing Transfer and Reactor

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 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.

Tags: coldfusion · orm

17 responses

  • 1 Joshua Curtiss // Mar 21, 2007 at 1:42 PM

    So Sean, are you an Active Record or Business Object developer? The Active Record approach makes more sense to me.
  • 2 Sami Hoda // Mar 21, 2007 at 2:48 PM

    Good to know!
  • 3 Dan // Mar 21, 2007 at 2:49 PM

    That is a very helpful summary. Thank you. :-)

    BTW, where would I find a good example of this "TQL" explained?
  • 4 Thomas Messier // Mar 21, 2007 at 3:58 PM

    I haven't had a chance to try Transfer yet but am quite fond of Reactor already. I'm gonna try to give Transfer a go soon. Any chance you could expand a bit on what exactly Transfer's TQL allows us to do, maybe with a few examples?
  • 5 Sean Corfield // Mar 21, 2007 at 4:27 PM

    @Dan, the best resource right now is the Transfer documentation available in the download. Mark is continuing to work on the TQL docs so SVN may contain a more up to date copy.

    @Thomas, yes, I will probably post some TQL examples shortly...
  • 6 Sean Corfield // Mar 21, 2007 at 4:29 PM

    @Joshua, I started out with Active Record - via Joe Rinehart's Arf! in fact - but soon found that I preferred the separate data access layer that Transfer provides.
  • 7 Sam Clement // Mar 21, 2007 at 6:07 PM

    Any thoughts why you prefer the separate data access layer that Transfer provides? I haven't had a chance to check out Transfer yet.
  • 8 Sean Corfield // Mar 21, 2007 at 8:19 PM

    @Sam, I prefer a cleaner separation of concerns. I like my business tier to be independent of my persistence tier. It also makes it easier to test things, in my opinion.
  • 9 Tom Chiverton // Mar 22, 2007 at 2:26 AM

    A good summary there.

    When you say 'caching' what do you mean Transfer caches (and Reactor doesn't) ? I'm sure Reactor won't regenerate objects at every single request and would hope Transfer wont either, for instance.
  • 10 Tony Petruzzi // Mar 22, 2007 at 6:37 AM

    Personally I would love to use either of these projects if they supported cascading deletes.

    I'm more prone to that Active Record way that Reactor does things, the only thing is I wish there was a way for Reactor to generate all the files at once rather than when you call create* the first time.
  • 11 Ken Dunnington // Mar 22, 2007 at 7:36 AM

    Thanks for this summary, Sean, it's quite helpful.

    I just started taking a look at Transfer 0.6.3 (it was the TQL addition that really peaked my interest) after having used Reactor extensively for the past year. It's definitely a different approach and I'm not done reading the docs yet, but I keep thinking that I'd end up using a lot of decorators, since I have a fair amount of custom code in my Reactor generated objects, and that seems like a bad idea to me (Active Record objects felt more naturally "functional" to me than Business Objects, plus I don't like defining CF code in XML.)

    Sean, what approach did you take moving from Reactor to Transfer in terms of more cleanly separating the persistence and business layers? Is it just a more robust Service Layer (like a UserService) that would handle stuff that might have been in a Reactor object previously? It seems like using things like ModelGlue's generic ORM methods would be harder on a Transfer-backed application. Or maybe I'm discounting the value of decorators too much.

    (Sorry for the rambling post!)
  • 12 Sean Corfield // Mar 22, 2007 at 10:46 AM

    @Tom, Transfer keeps the business objects cached in memory so it is not hitting the database all the time. Nothing to do with code gen.

    Transfer takes a very different approach than Reactor to code generation. Reactor has "development" and "production" modes that determine whether or not code is re-generated on each request. Transfer re-generates code only when it needs to - when the schema definition changes, for example.
  • 13 Sean Corfield // Mar 22, 2007 at 10:58 AM

    @Tony, cascading deletes are actually quite problematic in the general case. Have a look at this thread on the Transfer mailing list to see the sort of things that have to be considered:

    As for Reactor generating all the files, there is a "Reactor compiler" floating around that pre-generates everything for you. I think Jared Rypka-Hauer was the author and it was contributed into the core.
  • 14 Sean Corfield // Mar 22, 2007 at 11:03 AM

    @Ken, well, we actually found it fairly easy to switch from Reactor to Transfer because we had all the persistence code isolated in one layer - we only really had to modify the load/save code. That said, if we'd gone very far down the line with Reactor's OO queries, it would have been much harder.

    Also, for a while we ran with both Reactor and Transfer active, some tables managed by one and some by the other. In other words, it was a gradual switch as we touched each area of the application.

    As far as Model-Glue's generic database messages, there was no change needed at all: we simply configured MG to use Transfer and the TransferAdapter instead of Reactor and the ReactorAdapter. Scaffolding also continued to work unchanged. I worked with Mark Mandel and Joe Rinehart fairly extensively on that piece so that it would be seamless for everyone else. The MG core now includes both adapters and Joe has expanded all of the scaffolding functionality to include relationship management etc for both ORMs.
  • 15 Ken Dunnington // Mar 22, 2007 at 11:11 AM

    Thanks Sean, I think I will give Transfer a try on an upcoming small project.

    Tony: The compile feature Sean mentioned has been added to the reactor.reactorFactory in SVN, so you can easily call that onApplicationStart if needed.
  • 16 Jaime Metcher // Mar 22, 2007 at 1:20 PM


    Putting functions in the XML file is an alternative to using decorators. The decorators themselves are full-blown CFCs.

    If you create a decorator with save() and delete() methods (which are just simple delegations to the library), you get something that looks a lot like an ActiveRecord.

    If the delete() method then uses the builtin composition management methods to call other deletes, you've got cascading deletes with very little effort and a lot of control.

    It might just be me, but when it comes to cascading anything, I want control.
  • 17 Richard // Apr 21, 2007 at 10:39 AM

    @Jaime (re Tony) - totally with you on cascading deletes. The very mention of the phrase makes me feel nervous