I got a question today:
I was wondering if you could blog on the advantages with CF9 ORM using Hibernate versus something like the Active Record pattern Rails uses? I am not too familiar with Hibernate but go through Rails Envy once in awhile 🙂
This is an awesome question, and I’m going to tackle it, but I’m going to break it into a few sub questions. Before I do that, this is comparing apples to oranges. Active Record is a pattern and Hibernate is an ORM solution that uses a pattern named Data Mapper. I can’t speak to the entire reason for choosing Hibernate, as I’m not one of the engineers, but a quick survey shows it is the leading ORM solution in Java right now, which pushed us that way.
What are the differences between Data Mapper and Active Record?
The underlying one seems to be a philosophical one:
- Data Mapper looks to the objects to be the definition of the data; the database is just a place to store it.
Active Record looks to the database to be the definition of the data; the object is just a way to access it.
That’s an oversimplification I’m sure. Data Mapper requires you to map out each table and each column. Active Record by and large will detect things like tables and columns for you and expose them. Implementations of both patterns include the ability to tweak the configuration, but it looks like most Data Mapper implementations need to be configured. (As opposed to Active Record implementations like Rails that prefer convention over configuration.)
A practical consideration that occurs is that Active Record objects handle talking to the database with load, save, and delete methods; while Data Mapper objects get passed back to another object or function to translation back to the database.
There are also issues about performance and mapping. I won’t bother going into these as they are issues with implementation of the pattern and not the pattern itself.
Why did you go with Data Mapper over Active Record?
Two major reasons here:
- Hibernate uses the Data Mapper pattern
- Because the community (represented on the prerelease site) by and large asked for it.
I don’t remember the entire rationale behind this preference, but I will push responsibility on to the prerelease testers. 🙂 I think it is related to the two next issues.
Is ColdFusion ORM pure Data Mapper?
Not necessarily. Sure you create CFCs with properties. You then use the Entity functions to save them back to the database. You can have those properties actually create and update your database structure. That is clearly Data Mapper in action.
However, you can leave all of the properties in your CFCs blank, and ColdFusion will just populate it from the database. You can leave some of the details of your properties blank and ColdFusion will make assumptions about how they’re typed. These are philosophically Active Record features.
It comes down to ColdFusion making stuff easier, regardless of underlying philosophy. ColdFusion does both, to facilitate both database-focused and object-focused ORM implementations.
Can you create Active Record CFCs with ColdFusion 9’s ORM?
Yes. You can wrap the Entity functions in a CFC like this:
<cffunction name="save" access="public" returntype="void"><cfset EntitySave(This) /></cffunction>
Once you do that you can call your objects using the active record pattern of object.save(). In fact Bob Silverberg has started work on an Active Record CFC that you can just have all of your CFCs inherit from called Base Persistent ORM Object (Active.)
So hopefully this answered some of the questions around Hibernate, the Data Mapper pattern and the Active Record pattern in ColdFusion 9.
6 thoughts on “ColdFusion 9 ORM: Data Mapper versus Active Record”
Thanks for the mention, Terry. I just want to point out that I am not endeavouring to create an implementation of the Active Record pattern for CF9 ORM. It just so happens that I like to include a save() and a delete() method in my base object. Because I am still using Hibernate, the objects that extend my base object are not limited to residing in a single table, these objects can take advantage of the advanced inheritance mapping capabilities of Hibernate. I can also drive the database from the model (not vice versa, a la Active Record).
I’m not really trying to implement any particular pattern, I’m more concerned with adding behaviours to persistent objects that will make them smarter and easier to use. It’s not a big deal, but I know that the AR pattern has its detractors, and I’d prefer that people look at my project with an open mind.
Sorry to misrepresent you there, Bob.
No worries. It’s understandable that it could be interpreted that way.
This is the way we are going to implement hibernate support in Reactor. So you can still use Reactor objects along with overloaded methods etc, but the base class will allow you to do User.save()
“the way we are going to implement hibernate support in Reactor”?
Hey Mark, can you expound on that for a second?
CF9 ORM is Da Bomb.
Thank you very much, you saved my three days…