简体   繁体   English

使用JPA的Spring事务在AfterCompletion阶段抛出Exception

[英]Spring transaction that uses JPA throws Exception during AfterCompletion phase

I have a web application that uses the Spring Framework (3.1) and persistence through JPA (2.0) backened by Hibernate (4.1.1) 我有一个使用Spring Framework(3.1)的Web应用程序和通过Hibernate(4.1.1)备份的JPA(2.0)持久化

Hibernate Search is also enabled (4.1 RC). Hibernate Search也启用了(4.1 RC)。 Hibernate's Second Level cache is Infinispan (5.1.3). Hibernate的二级缓存是Infinispan(5.1.3)。

I also use Infinispan as Lucene (3.5) Directory Provider (for Hibernate Search). 我还使用Infinispan作为Lucene(3.5)目录提供程序(用于Hibernate搜索)。

Everything runs over XA transactions, with Bitronix (2.1.2) as JTA manager. 一切都在XA事务上运行,Bitronix(2.1.2)作为JTA管理器。

I have methods annotated with @Transactional . 我有使用@Transactional注释的方法。 When the method ends, and the transaction commits, the following exception occurs: 当方法结束并且事务提交时,会发生以下异常:

21:08:54,784  WARN BitronixTransaction:499 - Synchronization.afterCompletion() call failed for org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@704ecb9a
java.util.ConcurrentModificationException
    at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:390)
    at java.util.LinkedHashMap$KeyIterator.next(LinkedHashMap.java:401)
    at org.hibernate.engine.transaction.internal.SynchronizationRegistryImpl.notifySynchronizationsAfterTransactionCompletion(SynchronizationRegistryImpl.java:78)
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.sendAfterTransactionCompletionNotifications(TransactionCoordinatorImpl.java:335)
    at org.hibernate.engine.transaction.internal.TransactionCoordinatorImpl.afterTransaction(TransactionCoordinatorImpl.java:147)
    at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.afterCompletion(SynchronizationCallbackCoordinatorImpl.java:126)
    at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.afterCompletion(RegisteredSynchronization.java:61)
    at bitronix.tm.BitronixTransaction.fireAfterCompletionEvent(BitronixTransaction.java:497)
    at bitronix.tm.BitronixTransaction.commit(BitronixTransaction.java:244)
    at bitronix.tm.BitronixTransactionManager.commit(BitronixTransactionManager.java:120)
    at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1010)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy79.newTweet(Unknown Source)
    at com.lucho.controller.TweetController.newTweet(TweetController.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:311)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:116)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:101)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:182)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:323)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:173)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1805)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

You'll notice the Hibernate class "SynchronizationRegistryImpl". 你会注意到Hibernate类“SynchronizationRegistryImpl”。 This one holds a set of javax.transaction.Synchronization objects. 这个包含一组javax.transaction.Synchronization对象。 What I think is happening is that Hibernate itself is registered as a Synchronization in this set. 我认为正在发生的是Hibernate本身在这个集合中注册为同步。 So, 所以,

  1. After commit, two events fire: beforeTransactionCompletion and afterTransactionCompletion. 提交后,会触发两个事件:beforeTransactionCompletion和afterTransactionCompletion。
  2. beforeTransactionCompletion goes well. beforeTransactionCompletion进展顺利。
  3. afterTransactionCompletation starts and the method notifySynchronizationsAfterTransactionCompletion is called. afterTransactionCompletation启动并调用方法notifySynchronizationsAfterTransactionCompletion。
  4. This method calls afterCompletion on each of the Synchronization elements of the Set. 此方法在Set的每个Synchronization元素上调用afterCompletion。
  5. One of the item in the set (not the last) is an Hibernate item, which calls some clean up. 集合中的一个项目(不是最后一个)是一个Hibernate项目,它调用一些清理。
  6. This clean up empties the Set. 这个清理清空了Set。
  7. ConcurrentModificationException is thrown because the set was cleaned while it was being iterated. 抛出ConcurrentModificationException,因为在迭代时清除了集合。

Maybe I have configured Hibernate incorrectly. 也许我已经错误地配置了Hibernate。 My Spring XML are too big to be put here. 我的Spring XML太大了,无法放在这里。 Luckily some of you guys have an idea of why this is happening. 幸运的是,你们中的一些人知道为什么会这样。

More data (which may or may not be useful) to establish context: 建立背景的更多数据(可能有用也可能没用):

  • Other of the items in the Synchronization set belongs to Hibernate Search. 同步集中的其他项目属于Hibernate Search。
  • The database datasource is PostgreSQL. 数据库数据源是PostgreSQL。
  • I'm using XA because there is also an ActiveMQ JMS in the transaction, and at first Infinispan was set as a XA resource too (now it hooks to the JTA Synchronization). 我正在使用XA,因为事务中还有一个ActiveMQ JMS,并且最初Infinispan也被设置为XA资源(现在它挂钩到JTA同步)。
  • Spring Security is enabled. Spring Security已启用。
  • Hibernate connects to JTA by CMTTransactionFactory. Hibernate通过CMTTransactionFactory连接到JTA。
  • I'm not sure if the PersistenceContext is "transactional" or "extended", but from debugging it looks like the latter. 我不确定PersistenceContext是“事务性”还是“扩展性”,但是从调试看起来就像后者。

It turned out that there was more Infinispan configuration needed, that I didn't know it existed. 事实证明,需要更多的Infinispan配置,我不知道它存在。 In the transaction tag (under default configuration), even though I set up the transanction manager lookup, I had to explicity add the attribute transactionMode="TRANSACTIONAL" . 在事务标记中(在默认配置下),即使我设置了transanction manager查找,我也必须明确添加属性transactionMode="TRANSACTIONAL"

I was also using the default configuration for the caches that Hibernate uses, their names are: entity , local-query , and timestamp . 我还使用了Hibernate使用的缓存的默认配置,它们的名称是: entitylocal-querytimestamp There is a file named infinispan-configs.xml located in the hibernate-infinispan.jar that helps to setup the desired configuration. hibernate-infinispan.jar中有一个名为infinispan-configs.xml的文件,它有助于设置所需的配置。

UPDATE: disregard this answer. 更新:忽略这个答案。 The issue appeared again, and it's this bug . 这个问题又出现了,这就是这个错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring Web 服务客户端 XwsSecurityInterceptor afterCompletion 异常 - Spring web service client XwsSecurityInterceptor afterCompletion exception 事务需要异常 JPA / Spring - Transaction required exception JPA / Spring 测试期间的Spring Boot JPA事务-插入时不引发键冲突异常 - Spring Boot JPA Transaction during Test - not throwing key violation exception on insert 在JPA + Spring中异常后回滚事务 - Roll back transaction after exception in JPA + Spring 如果在控制器中引发异常,则Spring JPA回滚事务 - Spring JPA rollback transaction if Exception thrown in controller 当异常在子方法中抛出时,事务不会回滚 - Spring - Transaction not getting rolled back for when exception throws in child method - Spring Java Spring Boot JPA - 保存到数据库时引发 NullPointer 异常 - Java Spring Boot JPA - Throws NullPointer Exception when saving to database 为什么spring boot jpa hibernate投影会抛出异常? - Why spring boot jpa hibernate projection throws exception? spring数据JPA抛出异常并且不持久化数据 - spring data jpa throws exception and does not persist data 带有布尔字段的Spring JPA抛出“无法解析属性异常” - Spring JPA with boolean fields throws “cannot resolve property exception”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM