hibernate - getCurrentSession - 如果没有活动事务,则get无效

时间:2013-03-01 00:28:36

标签: java hibernate

我正在使用java命令行应用程序测试hibernate 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按照宣传的方式工作。

感谢。

2 个答案:

答案 0 :(得分:3)

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

我喜欢这样:

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

将其更改为此后,它有效:

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

答案 1 :(得分:0)

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

将属性名称hibernate.current_session_context_class更改为current_session_context_class,强制默认JTASessionContext

以下代码段来自休眠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