我正在使用java命令行应用程序测试hibernate 4.1.9。我已经将当前会话上下文配置为thread:
<property name="hibernate.current_session_context_class">thread</property>
但是当我调用sessionFactory.getCurrentSession()
时,它抛出一个异常:
Exception in thread "main" org.hibernate.HibernateException: get is not valid without active transaction
at org.hibernate.context.internal.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:348)
at com.sun.proxy.$Proxy9.get(Unknown Source)
....
我可以使用openSession
,这并不重要(毕竟这是一个测试)。我只是好奇为什么我不能得到方法getCurrentSession
工作的广告。
谢谢。
第一次调用sessionFactory.getCurrentSession()确实返回一个新会话。问题出在我的配置上。
我是这样写的:
<property name="hibernate.current_session_context_class">thread</property>
修改为this后,它工作了:
<property name="current_session_context_class">thread</property>
这是一个有点老的问题,但我想正确地回答它。
通过将属性名称hibernate.current_session_context_class
更改为current_session_context_class
,强制默认为JTASessionContext
。
下面的代码片段来自hibernate SessionFactoryImpl
。顺便说一句,Environment.CURRENT_SESSION_CONTEXT_CLASS
就是"hibernate.current_session_context_class"
。ThreadLocalSessionContext
导致此问题。
private CurrentSessionContext buildCurrentSessionContext() {
String impl = (String) properties.get( Environment.CURRENT_SESSION_CONTEXT_CLASS );
// for backward-compatibility
if ( impl == null ) {
if ( canAccessTransactionManager() ) {
impl = "jta";
}
else {
return null;
}
}
if ( "jta".equals( impl ) ) {
// if ( ! transactionFactory().compatibleWithJtaSynchronization() ) {
// LOG.autoFlushWillNotWork();
// }
return new JTASessionContext( this );
}
else if ( "thread".equals( impl ) ) {
return new ThreadLocalSessionContext( this );
}
else if ( "managed".equals( impl ) ) {
return new ManagedSessionContext( this );
}
else {
try {
Class implClass = serviceRegistry.getService( ClassLoaderService.class ).classForName( impl );
return (CurrentSessionContext)
implClass.getConstructor( new Class[] { SessionFactoryImplementor.class } )
.newInstance( this );
}
catch( Throwable t ) {
LOG.unableToConstructCurrentSessionContext( impl, t );
return null;
}
}
}
请查看ThreadLocalSessionContext.TransactionProtectionWrapper.invoke