Does ColdFusion have no real ORM frameworks?
Posted by Joe Rinehart at 9:12 AM
41 comments - Categories:
Frameworks
For the past month, I've been working like a madman with barely enough time to stop and spend with my family, much less blog meaningfully. During that time, my counterpart at Broadchoice Brian Kotek has still somehow managed to keep up fighting the good fight for common-sense OO design in ColdFusion.
Today's a little more relaxed at work, so I guess it's my turn to stir the pot a little. I'm sure this post will offend some folks who've worked long and hard on some open-source ColdFusio frameworks, but please bear with me: your work is good, saves many people much time, and is greatly appreciated. It's just been mislabelled. This post is largely about terminology, not effectiveness of technology.
ColdFusion has no ORMs (that I can find)
So, without further ado, here's what I'm postulating: there's not a single ORM framework for ColdFusion that's actually an object-relational mapping framework. Not even Transfer *really* meets the definition of ORM, even though it comes the closest.
I'm not trying to be destructive...
This post isn't a rant against the pseudo-ORM frameworks in the ColdFusion world. I've used the predominant ones and written three of my own: they're all great for increasing productivity and invaluable tools to ColdFusion developers.
...I'm illustrating differences between "real" ORM and ColdFusion "ORM".
For the past six months, I've only used Hibernate as an ORM. It represents a world a world of difference from how ColdFusion has approached object-relational mapping.
Here's the basis of our difference:
Object-Relational Mapping exists to allows you to work in purely objects and to use the framework to map the differences between object graphs and relational storage. It is *not* simply the abstraction and automation of SQL. In fact, some ORMs actually require you to write SQL: they just map what SQL to run for what operations!
The easiest example I can think of to illustrate this effectively is the idea of an an "audit" object. We'll approach it from the database side, as it's what we're most familiar with.
In just about any database design I've ever worked on, every entity has the idea of "last modified" and "last updated" columns. All too often (for my comfort), this gets reflected into properties on objects called things like getDateUpdated() or getDateCreated().
Let's pretend we've now got a new requirement to expose a getDaysSinceUpdate() getter on each object. To make it painful, let's pretend we've got 50 objects. Oi. No way we're going to go copy and paste that new <cffunction> onto every entity CFC in our system.
Good OO design says to encapsulate what changes, so we can take an obvious route: do away with these two properties and create an AuditTrail object with properties like getDateUpdated(), getDateCreated(), and getDaysSinceUpdated(). Once it's added to all of the other entities as a has-one composition, it's becomes _really_ easy to handle further cases such as tracking who performed the update.
We add them two our objects, using Transfer or Reactor or DataFaucet or whatever, and commit. Bam, a new AuditTrail table is in the database, and all of our objects now join to it via a foreign key.
The DBA, however, goes _nuts_. While we're using an optimized way of representing the new state and behavior in our object model, what we've done flies against optimally using the database. It'd be most efficient for it to just store dateUpdated and dateCreated as properties in the entities tables, not some soon-to-be-ginormous central table that's constantly going to get locked.
Sigh...that's not an ORM.
Our problem is that ColdFusion doesn't have any ORM that really maps the differences between our object graph and relations. Instead, we're using SQL abstraction toolkits calling themselves "ORMs" that treat object graphs and relational schemas as one and the same.
Conclusion
The world of "real" ORMs isn't hunky-dory either. Moving into JPA or plain Hibernate is a new world of units or work, sessions, detached vs. persistent instances, and all sorts of fun concepts. In many applications, the "simpler" approach taken by ColdFusion frameworks may actually be more effective (thought I'd wager with diminishing returns).
I have, however, had a wonderful time working with Hibernate, especially in the context of Groovy. Once the weirdness of not working in simple one-shot SQL statements wore off, I just code how I want things to work and don't worry much about the database (until it's time to create DTOs for Flex - then I'm a generated SQL control freak).
On a larger scale, I think we've seen a lot of places where the ColdFusion community has taken a looser interpretation of development terms, such as "data access object" and "object-relational mapping," than is widely accepted. In some cases, this can come back to haunt us: moving from what we think of as an ORM to something that really is an ORM can be a painful learning curve. At other times, I think it's been a pragmatic approach that opens up powerful new concepts to a larger development audiences.
Just...please...understand ORM before releasing a SQL generator with CFC hooks and putting "ORM" after its name. It's not the same.
Raul Riera wrote on 11/03/08 10:18 AM
Check out cfwheels.com it has a real ORM or OOP implementations, although I am not sure you understand what ORM is if you are talking about 50 objects (models) that have 50 functions to retrieve the same data