我正在努力将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)
配置是对的我只是写了必要的课程,如果需要更多,请告诉我们。任何帮助都将不胜感激。
答案 0 :(得分:0)
拦截器分为两种:ISession-scoped和 ISessionFactory作用域。
打开会话时指定了ISession范围的拦截器 使用重载的ISessionFactory.OpenSession()方法之一 接受一个IInterceptor。
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..
}
}
获取实体信息。
我希望它会有所帮助...