这是我对这个问题的一个简明答案
here
如果有人在Hibernate中遇到这个问题。显然很简单!
在hibernate中使用托管会话简化单元测试2006年11月6日
如果您曾经尝试在Hibernate中重用会话,您可能会遇到这个异常
org.hibernate.SessionException: Session is closed!
at org.hibernate.impl.AbstractSessionImpl.errorIfClosed(AbstractSessionImpl.java:49)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1319)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:301)
at $Proxy0.beginTransaction(Unknown Source)
....
thread
托管会话。通过这种类型的会话管理,Hibernate为您管理会话。当您第一次尝试使用会话时,Hibernate将创建一个会话并将其附加到本地线程。当您在会话中提交事务时,Hibernate将自动关闭会话,这意味着它不能被重用。
managed
会议。使用托管会话,您可以完全控制创建、刷新、提交和关闭会话。这就是方法。
hibernate.cfg.xml
更改属性
current_session_context_class
管理
.
创建
session
开始一个
transaction
在那里面
阶段
做这个
org.hibernate.classic.Session session = HibernateUtil.getSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
ManagedSessionContext.bind(session);
session.beginTransaction();
commit
一
在
阶段
做这个
ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
session.flush();
session.getTransaction().commit();
session.close();
为了在单元测试中使用这些代码,我创建了这个基本单元测试类,所有单元测试都扩展了这个类。每当我想创建一个新的
交易
createNewSessionAndTransaction()
. 为了提交会话事务,我调用
commitTransaction()
.
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.context.ManagedSessionContext;
import util.HibernateUtil;
import junit.framework.TestCase;
/**
* Abstract unit test with helper methods for managed session control
*/
public abstract class ManagedSessionUnitTest extends TestCase {
/**
* Create a new Session.
*
* For this method to work, the application managed session strategy has to
* be enabled. This basically means that the life of a session is controlled
* by you and and not by Hibernate.
*
* To enable the application managed session strategy set the property
* hibernate.current_session_context_class to "managed".
*
* Within this method we create a new session and set the flush mode to
* MANUAL. This ensures that we have full control over when the session is
* flushed to the database.
*/
protected org.hibernate.Session createNewSession() {
org.hibernate.classic.Session session = HibernateUtil.getSessionFactory().openSession();
session.setFlushMode(FlushMode.MANUAL);
ManagedSessionContext.bind(session);
return (org.hibernate.Session) session;
}
/**
* Start a new Transaction in the given session
* @param session The session to create the transaction in
*/
protected void startNewTransaction(Session session) {
session.beginTransaction();
}
/**
* Shortcut method that creates a new session and begins a transaction in it
* @return A new session with a transaction started
*/
protected org.hibernate.Session createNewSessionAndTransaction() {
Session session = createNewSession();
startNewTransaction(session);
return session;
}
/**
* Commit the transaction within the given session. This method unbinds
* the session from the session context (ManagedSessionContext), flushes
* the session, commmits the session and then closes the session
* @param session The session with the transaction to commit
*/
protected void commitTransaction(Session session) {
ManagedSessionContext.unbind(HibernateUtil.getSessionFactory());
session.flush();
session.getTransaction().commit();
session.close();
}
}