4

我正在使用 java 命令行应用程序测试休眠 4.1.9。我已将当前会话上下文配置为线程:

<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像宣传的那样工作。

谢谢。

4

2 回答 2

3

第一次调用 sessionFactory.getCurrentSession() 确实会返回一个新会话。问题出在我的配置上。

我有这样的:

<property name="hibernate.current_session_context_class">thread</property>

将其更改为此后,它起作用了:

<property name="current_session_context_class">thread</property>
于 2013-03-02T00:56:48.363 回答
0

这是一个有点老的问题,但想正确回答。

通过将属性名称更改hibernate.current_session_context_classcurrent_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

于 2017-09-12T18:46:57.480 回答