Tuesday, March 13, 2007

Intricacies of Hibernate

If you're a serious developer / software engineer, then you know how important it is to keep a system you're building as modular as possible for all the standard reasons: separation of concerns, testing, etc . To this end, I've been developing my systems at work to use Data Access Object interfaces, rather than giving them direct exposure to hibernate. One of the benefits of this is that it abstracts my business and presentation layers from my persistence layer. One of the detractors is that it makes it harder to do certain other things:
  1. Maintain efficiency when performing database operations
  2. Use Hibernate effectively when loading / storing objects.
Case in point: for the last two days I've been trying to figure out why my detached objects keep having exceptions thrown regarding dirty collection references when I try to update them. As it turns out, the Session.update() function is really best used within the context of a transaction, where you modify your business objects within the transaction, so the persistent objects never become detached (this last portion is a lot more meaningful if you're familiar with Hibernate parlance) However, in a well modularized Web application, your business, presentation and persistence layers are detached so one never knows that your business objects are being persisted with Hibernate, and as such you must 'detach' your business objects from their sessions. Updating them in a new session won't work if you want to use Session.update. Instead, you need to use Session.merge . The subtle difference between these two is that .update checks things like dirty member collections and caching, whereas .merge verbatim overwrites the existing state of your business objects' members in the database. It took me two days to realize this and I'm very pissed off. I really wish it had been mentioned in the Hibernate documentation.

No comments: