ITEEDU

Hibernate Gossip: Session 管理

Session是Hibernate运作的中心,对象的生命周期、事务的管理、数据库的存取,都与Session息息相关,就如同在编写JDBC时需关心 Connection的管理,以有效的方法创建、利用与回收Connection,以减少资源的消耗,增加系统执行效能一样,有效的Session管理, 也是Hibernate应用时需关注的焦点。

Session是由SessionFactory所创建,SessionFactory是执行绪安全的(Thread-safe),您可以让多个执行绪同 时存取SessionFactory而不会有数据共享的问题,然而Session则不是设计为执行绪安全的,所以试图让多个执行绪共享一个 Session,将会发生资料共享而发生混乱的问题。

在Hibernate参考手册中的 Quickstart with Tomcat 中,示范了一个HibernateUtil,它使用了ThreadLocal类别来建立一个Session管理的辅助类,这是Hibernate的Session管理一个广为应用的解决方案,ThreadLocal是 Thread-Specific Storage 模式 的一个运作实例。

由于Thread-Specific Stroage模式可以有效隔离执行绪所使用的数据,所以避开Session的多执行绪之间的数据共享问题,以下列出Hibernate参考手册中的HibernateUtil类:
HibernateUtil.java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.*;
import org.hibernate.cfg.*;

public class HibernateUtil {

private static Log log = LogFactory.getLog(HibernateUtil.class);

private static final SessionFactory sessionFactory;

static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
log.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}

public static final ThreadLocal session = new ThreadLocal();

public static Session currentSession() {
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}

public static void closeSession() {
Session s = (Session) session.get();
if (s != null)
s.close();
session.set(null);
}
}
在同一个执行绪中,Session被暂存下来了,但无须担心数据库连结Connection持续占用问题,Hibernate会在真正需要数据库操作时才(从连接池中)取得Connection。

在程序中可以这么使用HibernateUtil:
Session session = HibernateUtil.currentSession();
User user = (User) session.load(User.class, new Integer(1));
System.out.println(user.getName());
HibernateUtil.closeSession();
在Web应用程序中,可以藉助Filter来进行Session管理,在需要的时候开启Session,并在Request结束之后关闭Session,这个部份,在 JavaWorld 技术论坛Wiki 上有篇 在filter中关闭session 可以参考