I'm upgrading our project from Hibernate 3.0 to Hibernate 4.1.6. (And we are currently using spring 3.1)
I read in many articles and in HibernateTemplate documentation, that since version 4.0 HibernateTemplate is not supported and that I should replace it's usage with calling sessionFactory.getCurrentSession()
to get a session.
Since this project was started with older version of Hibernate, where the use of HibernateTemplate
was encouraged, we currently have 124 usages of HibernateTemplate
across our project. I'm afraid that replacing all these occurrences with sessionFactory.getCurrentSession()
might insert regression bugs in our project. In addition, there are some places where HibernateTemplate
was used in a non-transactional context, where there is no 'current' session. What should I do in those cases? Open a new session and handle (close) it myself? That wasn't the case when I used HibernateTemplate
.
Do you have some good strategy addressing these issues?
Thanks.
Relevant reading:
Okay, So this is what I actually did, I don't know if this is the best solution for this problem, but under our circumstances, and since I was looking for the most localized solution, it seemed best to me.
I have extended the springframework.orm.hibernate3.HibernateTemplate and created a new MyHibernateTemplate. The new template's main role is to override the doExecute method that most of the hibernate3.HibernateTemplate eventually lead to, and also supply some of the functionality that was provided by the old SessionFactoryUtils (like isSessionTransactional and applyTransactionTimeout).
The new doExecute replicates the logic of the old one, but instead of SessionFactoryUtils.getNewSession to get a session it first try to look for an open session getSessionFactory().getCurrentSession() :
boolean newSessionOpened = false;
Session session;
if (enforceNewSession){
session = SessionFactoryUtils.openSession(getSessionFactory());
newSessionOpened = true;
} else {
try {
// look for an open session
session = getSessionFactory().getCurrentSession();
}
catch (HibernateException ex) {
try {
// if there isn't an open session, open one yourself
session = getSessionFactory().openSession();
newSessionOpened = true;
} catch (HibernateException e) {
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
}
}
}
// is the open session, is a session in a current transaction?
boolean existingTransaction = (!enforceNewSession &&
(!isAllowCreate() || isSessionTransactional(session, getSessionFactory())));
You just need to close this session manually:
finally {
// if session was used in an existing transaction restore old settings
if (existingTransaction) {
//logger.debug("Not closing pre-bound Hibernate Session after HibernateTemplate");
disableFilters(session);
if (previousFlushMode != null) {
session.setFlushMode(previousFlushMode);
}
}
// if not and a new session was opened close it
else {
// Never use deferred close for an explicitly new Session.
if (newSessionOpened) {
SessionFactoryUtils.closeSession(session);
//_log.info("Closing opened Hibernate session");
}
}
I'm Trying keep this answer short, but if there are any questions I can elaborate further about this problem.
Check out this section in the docs. It says that SessionFactory.getCurrentSession()
is pluggable and there is a ThreadLocalSessionContext
implementation that keeps the 'current session' in the ThreadLocal
rather than a JTA transaction. ThreadLocalSessionContext will also close the Session at the end of the hibernate Transaction created from that Session, so you don't have to worry about closing the Session
yourself.
With regards to introducing regression bugs, upgrading a library will always have it's risks, especially so when it is something as core to your application as hibernate. The only advice I can give is to ensure your test suite has decent coverage before the upgrade. After all, that's the job of your test suite - to catch regression bugs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With