做一个Hibernate简单实验时, 碰到了这个异常: Session was already closed. 现在有点时间, 这样见了异常就想看看: 是怎么"触犯"了hibernate导致这个异常的抛出?
例子中的代码结构是这样的:
Session session = sessionFactory.getCurrentSession();
Transaction t = session.beginTransaction();
// do something with the session
t.commit();
session.close();
异常是在session.close()一句抛出来的,Hibernate中SessionImpl类close方法里有这样的代码:
if ( isClosed() ) {
throw new SessionException( "Session was already closed" );
}
而自己写用session来干事的代码中没有把session关掉,那是什么时候session给关掉了呢? 第一个怀疑点放到了Transaction的提交上,即t.commit()这一句.
那t.commit()里具体做了什么? 这得先看org.hibernate.Transaction接口都有哪些实现类, 例子中又是用的哪个实现类的commit方法. 不难发现Transaction接口有如下实现类:
debug跟到t.commit()代码里,发现是调用的JDBCTransaction实现类的方法. 一番找寻后终于在finally里看到了closeIfRequired方法,很是可疑!名字都起的那么"此地无银三百两".
一番跟踪这后,在transactionContext.managedClose 方法里找到了"犯罪现场": close()! 原来已经调用此方法给关掉了!
疑问解决了.
在关session前先通过isOpen方法做个判断也就OK了.
但这个小问题引起的思考给我深入drill Hibernate打开一条小道: session.beginTransaction()做了什么?具体把session给关掉的transactionContext是干啥的? 它们又与getCurrentSession方法有什么关联?敬请关注后续报道.