HIBERNATE  |  Register  | 
      SEARCH: 
   
News 
Features 
Documentation 
   Related Projects 
   External Documentation 
Download 
Forum & Mailinglists 
Support 
JIRA Issue Tracking
Wiki Community Area


JBoss.org



middlegen

JIRA Issue Tracking




      
Documentation > Community Area > Thread Local Session

Thread Local Session

Hibernate is designed to be useable in any kind of Java application, including applications that make extensive use of multithreading. So, unlike the ODMG API, Hibernate's native API does not use the current thread to maintain associations between Session and Transaction or between Session and application thread. This can be inconvenient for J2EE applications where access to a Session instance is always from a particular thread. It is particularly inconvenient when using a DAO pattern, when the different DAO classes need to obtain the (same) current session.

A common solution to this problem is to keep the Session in a ThreadLocal. The following class shows one possible implementation:

public class HibernateSession {

   public static final ThreadLocal session = new ThreadLocal();
   
    public static Session currentSession()
        throws NamingException, HibernateException {

      Session s = (Session) session.get();
      if (s == null) {
         SessionFactory sf = (SessionFactory) new InitialContext().lookup("SessionFactory");
         s = sf.openSession();
         session.set(s);
      }
      return s;
    }

    public static void closeSession() throws HibernateException {
       Session s = (Session) session.get();
       session.set(null);
       if (s != null) s.close();
    }
}

For a detailed explanation of ThreadLocal variables, see IBM Developer Works.

Related: Session Handling with the Spring Framework

The Spring Framework offers a convenient pre-built implementation of the Thread Local Session pattern, integrated with its transaction management infrastructure via a Hibernate-specific strategy. Additionally, there's special support for Thread Local Sessions in the JTA strategy too, enabling proper cache handling without any container-specific setup. Spring also offers IoC-style templating and AOP solutions for simplified Hibernate Session handling within DAOs, and easy configuration and handling of SessionFactory instances (be it local or from JNDI).

Together with similar support for plain JDBC and JDO, this allows for clear application layering with data access and business logic tiers. Regardless of the persistence mechanism, Spring provides the full comfort of high-level transaction management (with or without JTA). This can be combined with a Spring application context that wires up an application's beans, but any part can also be reused individually.

Note that Spring adopts a very lightweight approach. You can use a lot of features respectively classes in a library style, as everything is designed as a set of reusable JavaBeans. Don't be discouraged by the fact that Spring can serve as full application framework too. You're invited to review and leverage the Spring approach, no matter to what extent, before deciding to take the effort and risk of building such infrastructure in-house.

Data Access with the Spring Framework

Spring CVS


Steve Ebersole: Here is a variation on the above ThreadLocalSession. The main difference is that it undersands the concept of nested calls. Note that this usage is meant specifically for use in CMT session beans.

public class ThreadLocalSession
{
    private static final ThreadLocal sessionContext = new ThreadLocal(); 

    private Session session;
    private int level;

    public static Session currentSession()
    throws HibernateException
    {
        SessionFactory factory = ...;
        ThreadLocalSession tlSession = (ThreadLocalSession)sessionContext.get();
        if (tlSession == null)
        {
            tlSession = new ThreadLocalSession();
            tlSession.session = factory.openSession();
            tlSession.level = 0;
            sessionContext.set( tlSession );
        }
        tlSession.level++;
        return tlSession.session;
    }

    public static void closeSession()
    throws HibernateException
    {
        ThreadLocalSession tlSession = (ThreadLocalSession)sessionContext.get();
        if (tlSession == null)
        {
            return;
        }

        tlSession.level--;
        if (tlSession.level <= 0)
        {
            if (tlSession.session != null && tlSession.session.isOpen())
            {
                tlSession.session.close();
            }
            sessionContext.set( null );
        }
    }

}
      

coWiki web collaboration