Hi,
I'm sure this is a pretty frequent topic on this list, so I'm sure I'll get an answer pretty quickly ;-)
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?
Thanks in advance for any advice.
Regards,
/Slawek Zachcial
|