Created custom EnversPostInsertEventListenerImpl.onPostInsert, tried to call @Transactional method of Spring and got this exception:
{code:java} java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1042) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:587) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1435) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:491) at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3201) at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2411) at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220) at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:68) at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517) 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:504) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292) 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.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673) {code}
Problem is related to modification of ActionQueue by making new insertion in same transaction in EnversPostInsertEventListenerImpl.onPostInsert, exception ConcurrentModificationException is coming from ActionQueue (line 587) because of inner changes (EnversPostInsertEventListenerImpl.onPostInsert) of this list in ActionQueue (line 306) by same session. Problem can be avoided if you use new transaction, but it's no applicable in my case.
Also I can make necessary operations using EventSource inside argument 'event' of EnversPostInsertEventListenerImpl.onPostInsert, but it's really impossible to do via proxied Spring methods.
Did more tests, and it's not even Spring-related problem, it's enough to make this type of queries and this exception happens inside query in EnversPostInsertEventListenerImpl.onPostInsert (session is used from event) to get ConcurrentMidicationException :
PropertyTemplate template = pm.getTemplate(339L); Query<PersistedProperty> q = session.createQuery("select e from PersistedProperty e where e.propertyTemplate.id = ?1 and e.fileEntry.id = ?2", PersistedProperty.class); q.setReadOnly(true); q.setParameter(1, 339L); q.setParameter(2, fe.getId()); List<PersistedProperty> result = q.getResultList(); PersistedProperty pp = result.isEmpty() ? null : result.get(0); if (pp == null) { pp = new PersistedProperty(template, "Mass!", fe); } else { pp.setValue("Mass2!"); } session.merge(pp);
If I delete session.createQuery, everything works fine! I set up flush mode for Query and after that it works fine:
q.setHibernateFlushMode(FlushMode.MANUAL); |
|