Hibernate version: 3.0
Name and version of the database you are using: Postgres 7.4
We are trying to develop an application using Hibernate that uses lazy loading but does not expose this fact to any business objects. What we would like to do is have an object automatically load its uninitialized attributes on demand, without throwing a LazyInitializationException even though the session is closed. We are trying to keep a strict separation between the business layer and the data layer so as not to expose any particular persistence mechanism.
Assume we've got two persistent classes User and Permissions where User has a one-to-many relationship with Permissions.
When a business object invokes UserManager.loadUserByName() the UserManager will take the following steps:
create a session from the SessionFactory.
Load a User object via the session.
close the session.
return the User object.
The collection of permissions has not been referenced so the collection has not been initialized. I want to make it so that if the business object now tries to access the permissions it will not get the lazy initialization exception.
There are a few ways to solve this problem but the normal hibernate scenarios don't work for us.
Normal Hibernate Solution 1: Leave the Session open. - we can't do this as we don't know what the business layer is going to do with this object, how long it will take or if it will let us know when it is done. We can't risk having a connection leak.
Normal Hibernate Solution 2: Initialize the permissions collection before we return it. - we can't do this as it is an expensive operation and the business objects won't always need it.
Our Solution: Have the User class intelligently return the collection initializing it when neccessary. Use a variation on the
ThreadLocalSession pattern and instead of closing the Session in UserManager, disconnect it. This way in the User object we can have the following method:
Code:
public class User
{
...
public List getPermissions(){
if( !Hibernate.isInitialized( permissions ) )
try
{
ThreadLocalSession.reconnect();
Hibernate.initialize( permissions );
}
finally
{
ThreadLocalSession.disconnect();
}
}
return permissions;
}
}
Will this method cause problems with Hibernate persistence? I assume Hibernate will be using the getPermissions() method when it wants to persist the User object. This seems like everytime the User class is persisted the relationship would get initialized even if it hadn't needed loading or persisting. This could possibly be prevented by having the actual Hibernate persisted property being _permissions forcing hibernate to use private get/set_Permissions while the business layer is using the public getPermissions method.
Is there a simpler Solution that I am missing?
Also, this is just a single example. We would use this same model for almost all relationships in our persistent objects.
thanks,
Daniel[/url]