Recent Posts

Nov 3 2008

What makes a framework an ORM?

Earlier today, I posted an entry asking if ColdFusion has no real ORM frameworks.  It wasn't about any frameworks in particular:  it was about terminology and concept.  In the comments, there's a lot of questions about what makes a "true" ORM and whether it's a definition worth following or a term that should be loosely applied to anything that helps out with SQL. 

In the overall world of OO, there really is a series of criteria.  ORM technology exists to solve the differences between object models and relational schemas.  Here's the generally accepted list of the problem areas to be solved (from what I can gather, feel free to point out more).

Granularity

A User may be composed of two Address objects (homeAddress and businessAddress), but the database may choose to store this in one table to avoid joins.  An ORM should be able to resolve the granularity mismatch between the two.

Inheritance

A User might be extended into MaleUser and FemaleUser each with different composed objects (avoiding obvious jokes here, but it was an easy example!).  An ORM should be able to resolve this difference, allowing a user to save the state of both User subclasses.

Polymorphism

As soon as we introduce inheritance, we obviously have to deal with polymorphism.  If a UserGroup has-many User, and we ask the ORM to find all Users that are part of the Group, it should be able to understand, discrimate between, and populate the resulting collection with User, MaleUser, and FemaleUser instances as approriate, keeping the is-a contract in place.

Identify

This one's a killer.  In an object model, it's perfectly possible to have two instances of a single object (User with Id of 314).  In the database, primary keys keep the equivalent from occuring. 

This introduces a problem of identity mismatch.  In the database, there's one definition of identity (one record, Id of 314.  In the object model, there are two:  instance identity (two instances) and entity identity (two instances, but _one_ entity, id = 314).

An ORM should be able to resolve the concept of identity within its units of work against the relational database.

Associations - Plumbing

Object models relate instances via references.  Databases do it via foreign keys.  First, an ORM must be able to solve this plumbing mismatch, usually accomplished through foreign-key-identified proxy collections / objects or lazy loading.

Associations - Navigation and Direction

A second problem with associations is directional.  An object reference is, by nature, one-way.  A foreign key association, however, is multidirectional.  An ORM should constrain the free navigability of the data model into the directions specified by the object model.

Associations - Multiplicity

It gets worse and worse for associations.  In a relational database, any foreign key reference is either one-to-many or one-to-one.  When looking at an object model, however, it is impossible to determine the multiplicity of a collection-based association property:  it could be one-to-many or many-to-many.  An ORM needs to be able to solve this mismatch, providing a solution that allows for both one-to-many and many-to-many relationships between objects to be persisted.

 

12 comments - Posted by Joe Rinehart at 3:50 PM - Categories: Frameworks

Nov 3 2008

Does ColdFusion have no real ORM 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.

39 comments - Posted by Joe Rinehart at 9:12 AM - Categories: Frameworks

Oct 21 2008

Don't fax me: I'll fax you. (I'm a jerk.)

This morning I've been getting calls every two minutes or so from a fax machine that's obviously trying to dial a wrong number that happens to be my own.  Thanks to caller ID, I was able to track the number back to a small company in Virginia.

I called their front desk (I love Google) and asked them to knock it off.  They confirmed the fax number was theirs and that they'd be happy to.

For the next ten minutes, no rings, no beeps in ear.

Once it started back up, I called again.  Asked them to stop, stating that if they didn't I'd simply occupy their fax line to stop my home line from ringing.

I don't think they understood what I meant, because their fax line is still busy receiving the full 110-page PDF of the federal bailout bill.  If that doesn't do it, I'll move on to the instructions (including tax tables) for the IRS 1040.

9 comments - Posted by Joe Rinehart at 10:59 AM - Categories: Off Topic

Previous Posts

Oct 21

Groovy ate my Actionscript's semicolons!

5 comments - Posted by Joe Rinehart at 10:57 AM - Categories: Flex |

Sep 8

Broadchoice Workspace Revealed!

0 comments - Posted by Joe Rinehart at 7:22 AM - Categories:

Sep 2

Get yourself a Wee Dram o'Scotch!

4 comments - Posted by Joe Rinehart at 8:49 AM - Categories: Conferences and Speaking Engagements |

Aug 22

Don't Flex your G-String

1 comments - Posted by Joe Rinehart at 2:56 PM - Categories: Flex and Java |