Monday, February 26, 2007

ORMs are not just about objects

It seems most of my professional career has been built around using java to pull and put stuff in a database of some sort. Whether we are talking about an eGovernment web interface or a content management system I've done a lot of work with java and databases. The past few years I have grown to use and love Object Relational Mappings (ORMs), specifically Hibernate.

ORMs in the software development world are almost a religion, you either love or hate them. I love them because they take a lot of the "Busy" work out of working with databases. Plus they allow you to stay in an object oriented world rather than moving from java to JDBC, which is much more functional.

Usually when I come across someone who is against ORMs they say "Well it doesn't fit with what we are trying to do" or "Its overkill" or "It adds complexity to a simple interface like SQL". And its true, it can be overkill for some projects and it is another thing to learn and manage. Some people would feel more comfortable pulling fields out of a result set than working with the Hibernate API.

However, I think a lot of those people don't fully appreciate what ORMs give you. Of course the most visible is the java object to sql mapping. But another HUGE benefit is persistent lifecycle. I've seen JDBC code that passes a connection through multiple paths, updating a row here, then updating it again, and so on and so on. From an outsider it becomes almost cryptic what is happening and where. And if you change your schema at anytime, you may not know the implications until the actual code is run.

In ORM land lets say I have a User class, that maps to a table some where. Lets say I do the folowing:


User user = new User("Jon");
session.save(user);
....
user.setAge(18);
session.saveOrUpdate(user);
...
user.setAge(22);
sesion.update(user);
...
user.setIsMaleGender(true);
session.update(user);
...

session.commit();


Now in JDBC land this would end up sending several SQL statements to the database, each being processed, locking rows, etc. The code who set the users's age as 19 may not know that later some other code has set it to 22 unless they queried the db again in the same session. If some logic was later performed with the assumption that the age is 19, that could be a problem.

In Hibernate (or most ORMs) the session would keep track of that user object once it is associated with the session ( after the first session.save()) and keep track of updates and even retrievals. Periodically throughout the lifetime of the session hibernate my flush the user object to the db or it may wait until the end. Doesn't matter, however you do know that throughout that session you are not dealing with stale data.

This is an incredibly efficient, complex and useful function that you get for free just by using an ORM. As your code gets more complex and is re factored a few times, problems that can arise from using stale data that can be very difficult to track down (I should know, I've done it for a while).

So whats the moral? ORM just isn't about objects and abstracting SQL statements. Its about treating persistent data as actual entities in your program. If you think an ORM isn't for your app, I challenge you to look again. The complexity of the added layer may simplify things in other places.

No comments: