Billy Newport, of IBM recommends against the use of ThreadLocal with WebSphere:
[url]http://www.devwebsphere.com/devwebsphere/2005/06/dont_use_thread.html
[/url]
As a comment to this article, Gavin King of Hibernate points out that Hibernate does not use ThreadLocal, which is true. But Hibernate certainly advocates the use of ThreadLocal by its users, for example, in the CaveatEmptor sample.
[url]http://cvs.sourceforge.net/viewcvs.py/hibernate/CaveatEmptor/HiA/src/java/org/hibernate/auction/persistence/HibernateUtil.java?rev=1.2&view=markup
[/url]
Newport, in the above article, says:
Quote:
You may get away with using ThreadLocal on a thread but as soon as you return and give that thread back to the application server then you can't assume:
1. You'll get called again on the same thread.
2. Even if you do get the same thread, it may have different threadlocal values as it may have been used by other applications.
I'm not concerned about point 1 but I am concerned about point 2. In particular, I'm concerned about this snippet of code from the CaveatEmptor HibernateUtil sample:
Code:
/**
* Retrieves the current Session local to the thread.
* <p/>
* If no Session is open, opens a new Session for the running thread.
*
* @return Session
*/
public static Session getSession()
throws InfrastructureException {
Session s = (Session) threadSession.get();
try {
if (s == null) {
log.debug("Opening new Session for this thread.");
if (getInterceptor() != null) {
log.debug("Using interceptor: " + getInterceptor().getClass());
s = getSessionFactory().openSession(getInterceptor());
} else {
s = getSessionFactory().openSession();
}
threadSession.set(s);
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
return s;
}
/**
* Closes the Session local to the thread.
*/
public static void closeSession()
throws InfrastructureException {
try {
Session s = (Session) threadSession.get();
threadSession.set(null);
if (s != null && s.isOpen()) {
log.debug("Closing Session of this thread.");
s.close();
}
} catch (HibernateException ex) {
throw new InfrastructureException(ex);
}
}
If Newport is right that we should worry about threads being reused by the pool, is the above code not dangerous? Thread A uses session, closes using closeSession(). Later Thread B comes along, gets the same thread from the pool without expecting it, calls getSession(), finds the thread isn't null, but it's been closed, and therefore will fail.
I haven't experienced this yet, my application isn't written yet, but can someone tell me if I should shy away from using ThreadLocal in this Hibernate-recommended way, if I am also running under WebSphere? Or will I be okay, but perhaps need to make the getSession() member look for a closed session and react accordingly?