Tuesday, November 18, 2008

Is it okay to violate OO or Relational principles when mapping objects to the database?

This seems to be a big topic in my work life lately. It was a heated topic at this last Sacramento Java User's group. I've also been criticized at work for allowing my Domain model to intrude on the Relational model or vice versa when building an application from scratch. From that point of view I would have to say guilty as charged.

My opinion is that the goal of using an ORM tool such as hibernate is to simplify the job of translating business object into the relational persistence model. In the good-old-days I used to seperate my DOAs from my "rich" domain model objects. My DAOs were essentially dumb objects that were only used to make JDBC queries. The Domain model was rich with behavior and was not directly influenced by the relational model. Of course then I had an issue of how the Domain model communicated with these DAOs. The DAOs weren't really Objects in the pure sense because I had isolated them from implementing any business behavior.

An ORM purist might argue that you could change the model above by mapping those Domain objects to the relational model. This is possible and I've worked on a number of projects that did exactly that. The difficulty there is that you have what I call the "big mapping" layer that deals with the logic of mapping these domain objects to the relational model. This quickly becomes one of the most complex pieces of the application and usually only one or two experts in that particular ORM tool have any idea of what is really going on. ORM purists might argue that this is just fine and that you business developers shouldn't need to know what is going on with the persistence layer. But in practice I have found that those experts disappear and eventually whatever developes are left standing end up inheriting this mapping layer.

Maybe because of similar experience to mine, the current trend seems to be a "compromised" ORM approach. If you take the Grails framework as an example (I believe the same tends to hold true for Seam or JEE 5 applications using annotations), the mapping layer is quite simple and is held within the Domain objects themselves. Although capable of mapping in the same big mapping solution as before, typically a developer builds the Objects before the relational model and the relational model is generated from the Domain objects. I've found in practice that the Domain model tends to intrude on the Relational model, although the technology doesn't neccessitate this as Grails just uses hibernate under the covers and is certainly capable of using the big mapping approach.

I would argue that this compromise is the best of all worlds for most situations. I have found that you are able to achieve an intelligent and simple Domain model and an efficient, normalized relational model. In this compromised approach, you will almost certainly end up with Domain ojects that don't make a lot of business sense (such as List of Value objects) and with a Relational model that may have compromised certain normative principles to encourage simplification of the mapping. I argue that this isn't necessarily a bad thing. What you end up with is a much simpler application that everyone can wrap their heads around which, from my perspective, is the primary purpose anyway.

What do you all think?


Jim Shingler said...

Wow, I can't wait to see the comments on this one, . . . LOL.

I have some thought that I will share when I have a chance.

I think there is a pragmatic solution.

More later

iamsteveholmes said...

I can't wait to hear them. I thought the way I was doing it was pretty pragmatic but I'm always open to a better way.

Monkey Search