在执行hibernate Interceptor后,它通过spring事务关闭会话管理

时间:2017-11-15 06:32:45

标签: java spring hibernate session interceptor

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

根据我的研究,目前拦截器似乎存在问题。如果我注释掉hibernate拦截器,那么一切正常。

问题是如何发生的:我在整个应用程序中使用spring托管事务,并使用ApplicationContextAware访问hibernate拦截器中的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)

配置是对的我只是写了必要的课程,如果需要更多,请告诉我们。任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:0)

来自NHibernate documentation

  

拦截器分为两种:ISession-scoped和   ISessionFactory作用域。

     

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

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

注册了一个ISessionFactory范围的拦截器   构建ISessionFactory之前的配置对象。在这   case,提供的拦截器将应用于所有打开的会话   从那个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..
            }
}

获取实体信息。

我希望它会有所帮助...

相关问题