This week's giveaway is in the EJB and other Java EE Technologies forum. We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line! See this thread for details.
In our application, we get this "org.hibernate.SessionException: Session is closed!" very frequently and it is not consistent, at some point we would get this exception, and at some point we dont get this, Well i googled about this exception and also searched in Javaranch site, but didnt help me. if some body knows what is causing the issue please advice.
The actual exception:
sessionFactory object created in the applicationcontext.xml file is injected to all the DAO classes and we get the session object using the following statement in the DAO classes:
The exception is thrown at "Transaction tx = session.beginTransaction();" line, since the session is already closed, when we try to begin the transaction, but it is very clear that we are getting the new session object, but some how for some reason it is automatically getting closed, not sure why, main problem is this exception is not consistent, for a single use case it throws this exception at some time and it doesn't at other times, I am not even sure like how to reproduce this. I learnt that a session object has to be created for a request level, some how it has not been followed in ours. If some one have any thoughts to get rid of this exception please share
If you are using Spring use Spring for the transaction management as well.
From the reference manual
Hibernate 3 has a feature called contextual sessions, wherein Hibernate itself manages one current Session per transaction. This is roughly equivalent to Spring's synchronization of one Hibernate
Session per transaction.
Spring's LocalSessionFactoryBean supports Hibernate's SessionFactory.getCurrentSession() method for any Spring transaction strategy, returning
the current Spring-managed transactional Session even with HibernateTransactionManager. Of course, the standard behavior of that method remains the return of the current Session associated
with the ongoing JTA transaction, if any. This behavior applies regardless of whether you are using Spring's JtaTransactionManager, EJB container managed transactions (CMTs), or JTA.
So in short add Spring transactional support
Also I would encourage you to take advantage of Spring's unified unchecked exception translation. This is as simple as adding a component scan (also means you don't have to manually configure the beans in XML) and a @Repository stereo type annotation to your DAO class.
For example add this to your config
Now you have your Repository class. Note this bean will automatically be created as long as it is in a package defined in your component scan.
We can take advantage of the same type of automatic bean creation for our Service
This is not the only way to do it but it ls the recommended way. If you let Spring manage the transactions as well I think your issue will go away.
First of all thank you Bill for your time in responding to this, the problem with the current code is the session management, i.e even though we open a new session by using "sessionFactory.getCurrentSession();", the session is getting closed automatically, the session object is not available for us, we are not finding any difficulty in managing the transaction. I think the code below is something to do for transaction management
Please advice if this is going to solve the session object issue
So you do have the below code in your application? If you don't you should add it.
Remove this property
You are overriding Spring which sets this to SpringSessionContext.class. This is almost certainly at least part of your problem.
Spring manages your session objects. These session objects that it manages are tied to Spring transactions. So the fact that you are getting that error means to me that it is most likely due to how you are handling transactions.
in other words don't do this
unless you want to manage the life cycle of the session yourself in which case you need to call session.open() and session.close()
Instead use the framework to handle transactions. I would take advantage of spring aspects and the declarative approach using @Transactional like I described earlier its both cleaner and more simple, but if you want to do it pragmatically you can do that with Spring as well. Follow the example outlined in the reference manual. See the below link: