【问题标题】:After executing hibernate Interceptor it close session manage by spring transaction执行休眠拦截器后,它关闭由春季事务管理的会话
【发布时间】:2017-11-15 06:32:45
【问题描述】:

我正在将 spring 和 hibernate 从版本 3.x 升级到 4.x。 所以在旧版本中一切正常,但升级到新版本后,我遇到了一个奇怪的错误。

根据我的研究,现在问题似乎出在拦截器上。如果我注释掉休眠拦截器,那么一切正常。

问题是如何发生的:我在整个应用程序中使用 spring 托管事务,并且还使用 ApplicationContextAware 在休眠拦截器中访问 spring 服务。因此,如果任何单个查询从拦截器执行而不是从下一个查询执行,它会给我一个错误,即会话已关闭。如果我从拦截器中注释掉查询,那么每件事情都会像我所说的那样找到。

我有多个会话工厂和事务管理器。 我的配置如下:

<bean class="com.test.MyInterceptor">
<constructor-arg type="java.lang.String" value="my_config" />
/bean>
<bean id="sf" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="Ds"/>
    <property name="mappingResources">
        <list>
            <value>....</value>
        </list>
    </property>
    <property name="entityInterceptor" ref="myInterceptor" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">...</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.c3p0.minPoolSize">...</prop>
            <prop key="hibernate.c3p0.maxPoolSize">...</prop>
            <prop key="hibernate.c3p0.timeout">120</prop>
            <prop key="hibernate.c3p0.max_statement">..</prop>
            <prop key="hibernate.c3p0.unreturnedConnectionTimeout">600</prop>
            <prop key="hibernate.c3p0.debugUnreturnedConnectionStackTraces">true</prop>
            <prop key="hibernate.hbm2ddl.auto">none</prop>
            <prop key="hibernate.c3p0.testConnectionOnCheckin">false</prop>
            <prop key="hibernate.c3p0.testConnectionOnCheckout">true</prop>
            <prop key="hibernate.default_batch_fetch_size">5</prop>
        </props>
    </property>
</bean>

<bean id="transactionTx" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sf"/>
</bean>

我的拦截器和服务看起来像:

public class MyInterceptor extends EmptyInterceptor implements ApplicationContextAware {

private ApplicationContext context;
    @Override
    protected void handleAfterTransactionCompletion(Transaction arg0) throws CallbackException {
        // after executing this it breaks my spring transaction.
        Entity entity = service.get(id);
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.context = context;
    }
}

public class ServiceImple {

......................
...................

    @Transactional
    public Entity get(long id) {
        return dao.get(id);
    }
}

错误堆栈跟踪是:

(main)  SessionImpl ERROR: HHH000087: Exception in interceptor afterTransactionCompletion()
org.springframework.orm.hibernate4.HibernateSystemException: This TransactionCoordinator has been closed; nested exception is org.hibernate.ResourceClosedException: This TransactionCoordinator has been closed
    at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:218)
    at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:344)
    at org.springframework.orm.hibernate4.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:309)
    at org.springframework.orm.hibernate4.HibernateTemplate.get(HibernateTemplate.java:419)
    at org.springframework.orm.hibernate4.HibernateTemplate.get(HibernateTemplate.java:412)
    at code......................
    at sun.reflect.GeneratedMethodAccessor95.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy70.get(Unknown Source)
    at code......................
    at org.hibernate.internal.SessionImpl.afterTransactionCompletion(SessionImpl.java:508)
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.afterTransaction(TransactionCoordinatorImpl.java:151)
    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.afterTransactionCompletion(JdbcTransaction.java:138)
    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:180)
    at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:761)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:485)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:291)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
Caused by: org.hibernate.ResourceClosedException: This TransactionCoordinator has been closed
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.getTransaction(TransactionCoordinatorImpl.java:191)
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.isTransactionInProgress(TransactionCoordinatorImpl.java:167)
    at org.hibernate.internal.SessionImpl.afterOperation(SessionImpl.java:476)
    at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2456)
    at org.hibernate.internal.SessionImpl.get(SessionImpl.java:949)
    at org.springframework.orm.hibernate4.HibernateTemplate$1.doInHibernate(HibernateTemplate.java:427)
    at org.springframework.orm.hibernate4.HibernateTemplate.doExecute(HibernateTemplate.java:341)

配置是正确的,我刚刚写了必要的类,如果需要更多,请告诉我们。任何帮助将不胜感激。

【问题讨论】:

    标签: java spring hibernate session interceptor


    【解决方案1】:

    来自NHibernate documentation

    拦截器有两种形式:ISession-scoped 和 ISessionFactory 范围内。

    在打开会话时指定 ISession 范围的拦截器 使用重载的 ISessionFactory.OpenSession() 方法之一 接受 IInterceptor。

    ISession session = sf.OpenSession( new AuditInterceptor() );
    

    一个 ISessionFactory 范围的拦截器注册到 构建 ISessionFactory 之前的配置对象。在这 情况下,提供的拦截器将应用于所有打开的会话 从那个ISessionFactory;除非打开会话,否则这是真的 明确指定要使用的拦截器。 ISessionFactory 范围的 拦截器必须是线程安全的,注意不要存储 特定于会话的状态,因为多个会话将使用它 拦截器(可能)并发。

    new Configuration().SetInterceptor( new AuditInterceptor() );
    

    所以,基本上你可以检查事务是否已提交或什么:

    if ( tx.WasCommitted ) {
    // do stuff
    }
    

    你也可以覆盖

    public override bool OnSave(object entity, 
                                    object id, 
                                    object[] state,
                                    string[] propertyNames,
                                    IType[] types)
    {
      //get entity with
           if ( entity is Entity ) {
                   get entity properties: Id etc..
                }
    }
    

    获取实体信息。

    希望对你有帮助……

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多