前面所有的Hibernate应用使用Session时都用到了HibernateUtil工具类,因为该工具类可以保证将线程不安全的Session绑定限制在当前线程内------也就是实现一种上下文相关的Session。
public class HibernateUtil
{
public static final SessionFactory sessionFactory;
static
{
try
{
//采用默认的hibernate.cfg.xml来启动一个Configuration的实例
Configuration configuration = new Configuration()
.configure();
//由Configuration的实例来创建一个SessionFactory实例
sessionFactory = configuration.buildSessionFactory();
}
catch (Throwable ex)
{
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
//ThreadLocal可以隔离多个线程的数据共享,因此不再需要对线程同步
public static final ThreadLocal<Session> session
= new ThreadLocal<Session>();
public static Session currentSession()
throws HibernateException
{
Session s = session.get();
//如果该线程还没有Session,则创建一个新的Session
if (s == null)
{
s = sessionFactory.openSession();
//将获得的Session变量存储在ThreadLocal变量session里
session.set(s);
}
return s;
}
public static void closeSession()
throws HibernateException
{
Session s = session.get();
if (s != null)
s.close();
session.set(null);
}
}
从
Hibernate3开始,Hibernate增加了
SessionFactory.getCurrentSession( )方法,该方法可直接获取上下文相关的Session。上下文相关的Session的早期实现必须依赖于JTA事务,因此比较适合于在容器中使用Hibernate的情形。
从Hibernate3.1开始,SessionFactory.getCurrentSession( )的底层实现是可插拔的,Hibernate引入了CurrentSessionContext接口,并通过hibernate.current_session_context_class参数来管理上下文相关Session的底层实现。
CurrentSessionContext接口有如下三个实现类:
① org.hibernate.context.JTASessionContext:根据JTA来跟踪和界定上下文相关Session,这和最早的仅支持JTA的方法是完全一样的。
② org.hibernate.context.ThreadLocalSessionContext:通过当前正在执行的线程来跟踪和界定上下文相关Session,也就是和上面的HibernateUtil的Session维护模式相似。
③ org.hibernate.context.ManagedSessionContext:通过当前执行的线程来跟踪和界定上下文相关Session。但是程序需要使用这个类的静态方法将Session实例绑定,取消绑定,它并不会自动打开、flush或者关闭任何Session。
如果使用ThreadLocalSessionContext策略,Hibernate的Session会随着getCurrentSession( )方法自动打开,并随着事务提交自动关闭,非常方便。
对于在容器中使用Hibernate的场景而言,通常会采用第一种方式。
对于独立的Hibernate应用而言,通常会采用第二种方式。
为了指定Hibernate使用哪种Session管理方式,可以在hibernate.cfg.xml文件中增加如下片段:
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.current_session_context_class">jta</property>
对于第三种不太常用的Session管理机制,可在配置文件中简写成:managed。对于使用当前线程来界定上下文相关Session的实例程序,可以参考李刚《轻量级JavaEE企业应用实战》codes\06\6.8路径下的currentSession应用。