If you have been backing your web application using Hibernate, you would have certainly encountered this famous issue. How to use the lazy loaded objects in View? When you try to use the lazy loaded objects in your jsps, you will encounter the below exception,
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
As I mentioned in my previous post, this would occur when we try to initialize a lazily loaded entity after the underlying session is closed. But there’s a great work around for this issue provided by Spring framework, OpenSessionInViewFilter. We just need to plug this filter to our web.xml and thats it, you gotta do nothing. This filter takes care of opening up a session when a request arrives and keeps it open till the response is sent back to the client. This means the session will be alive in the jsps too
Wow!! that’s really great indeed but at the cost of below limitations.
Long connection hold time
One good thing about hibernate is everything can be (is) done lazily. For instance, the db connections will be retrieved only when we try to execute a query and not when you open up a session. Hibernate allows provides a couple of connection release strategies that can be configured in the hibernate prperties,
connection_release_mode=after_transaction | after_statement
after_transaction will make sure that the connection is released immediately after the transaction is committed/rolled back. after_statement will release the connection immediately after executing a statement.
So where is the long connection hold time? The issue again comes with the lazily loaded proxy objects. Under normal circumstances, hibernate attempts to release the connection after every operation (You can see the source for the methods get/load in SessionImpl. The finally block has a call to afterOperation that takes care of releasing the connection). But when you try to initialize a lazy loaded proxy object, hibernate makes a call to,
session.immediateLoad()
This method doesn’t release the connection after the object is loaded. What the heck!! So the connection is held by the session till it is closed. In case of the OpenSessionInViewFilter, it’s till the response is sent back to the client. So the maximum time the connection is held is equal to the time that you take to respond to the request.
Danger of Memory/Connection leaks
The OpenSessionInViewFilter adds value when the request is processed within the same thread but consider the case where you want to parallelize the work using multiple threads. Bang!! your session per request model is gone. You would have coded your application under the assumption that session will be kept open throughout the request life time.
If you assume still the session per request model to work, you would start seeing all crazy lazy exceptions from hibernate. Since you are not handling the sessions in those threads, and Spring DAO anyways creates the session internally, you will be leaking out the sessions and hence the connections (as explained in limitation one above).
You are now force to handle the session cleanup on your own. Fortunately I managed to find a *hack* to fix this issue. It just makes the thread to do the cleanup once the job is done.
public class HibernateSessionAwareThread extends Thread {
public void run() {
super.run();
cleanup();
}
public void cleanup() {
Session session = TransactionSynchronizationManager.unbindResource(factory);
SessionFactoryUtils.closeSession(session);
}
}
You can make use of this thread when you want to parallelize the work. If you are extending the thread, override the run method and call super.cleanup() at the end of the job,
public class MyThread extends HibernateSessionAwareThread {
public void run() {
try {
// all the hibernate related job
} catch(Exception e) {
// Handle the exception
} finally {
super.cleanup();
}
}
}
If you pass on a Runnable interface to the thread, the session cleanup is automatically taken care of by the HibernateSessionAwareThread thread.
One might say that a thread should not know anything abt the session handling. But the idea here is to make the application return a custom thread for processing. A bad design but quite a neat hack !!










