Wednesday, April 13, 2005

Hibernate lazy loading and HttpSession-scoped objects

In order for lazy loading to work (either collections or proxy) Hibernate requires the session in which these lazy objects were created to be open when when accessing them. Otherwise you'll get LazyInitializationException. To work around this issue the "Open session in view" pattern is used.

This works fine for request-scoped objects.

But how to deal with session- or application-scoped objects. Let's say you have an Account that has several Users. When a user logs into the application you put the reference to this user object into the session. The user's account (along with the list of its users) is rarely used and you don't want to fetch all account users for every logged-in user, so you declare it as lazy (proxy).

If you try to access the account outside the request in which the user was loaded you'll get LazyInitializationException.

Now Hibernate.initialize() doesn't really cut it. If I use it in my DAO layer then it means that I make assumption how my object will be used. Doing it in business layer is not good either as this would mean that the business layer knows what is the DAO implementation.

In addition Hibernate.initialize() would have to be called on any lazy property (proxy) or collection - one by one, which is not good either.

All this is a documented Hibernate behavior. I'm wondering why Hibernate couldn't open a session or pick one that is open and then do some magic to reassociate the object and have all these lazy loading always working...

What are the best practices to handle such longer-than-request-scoped objects? Is Hibernate.initialize() the only option?