4 Replies Latest reply on Mar 9, 2016 9:37 AM by Giovanni Lovato

    Transactional CDI event from JPA callback

    Maxim Frolov Newbie

      Sending transactional CDI events from an JPA callback during a managed flush throws IllegalStateException (ARJUNA016082) in Wildfly 8.2.0.Final.

      The following Arquillian test project on GitHub: https://github.com/wrungel/bugs/tree/master/tx-observer-test shows the error.

      The JPA Listener (CDI Event sender):

      public class UpdateListener {
          @PreUpdate
          public void callback(Object object) {
               if (object instanceof FooEntity) {
                   getBeanManager().fireEvent(object);
               }
          }
      }

      CDI event observer:

      public class UpdateObserver {
           public void BEFORE_COMPLETION(@Observes(during = TransactionPhase.BEFORE_COMPLETION) FooEntity foo) {
               ...
           }
      }

      Transactional service:

      @Transactional
      public class FooService {

          @PersistenceContext(unitName = "default")
          EntityManager em;

          public void managedFlush() {
              // change entity property:
              em.find(FooEntity.class, ID).setName(UUID.randomUUID().toString());
          }
      }

      Calling managedFlush() causes the following error:

      WARN  [com.arjuna.ats.arjuna] ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffffac136c07:4115d5ad:553685a6:11, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@458cbc17 >:
      javax.persistence.PersistenceException: error during managed flush
          at org.hibernate.jpa.spi.AbstractEntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1887) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorNonTrackingImpl.beforeCompletion(SynchronizationCallbackCoordinatorNonTrackingImpl.java:119) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:50) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:358) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:91) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1166) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:126) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75)
          at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.endTransaction(TransactionalInterceptorBase.java:147) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:93) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.jta.cdi.transactional.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:52) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_20]
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_20]
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_20]
          at java.lang.reflect.Method.invoke(Method.java:483) [rt.jar:1.8.0_20]
          at org.jboss.weld.interceptor.reader.SimpleInterceptorInvocation$SimpleMethodInvocation.invoke(SimpleInterceptorInvocation.java:74) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.interceptor.chain.AbstractInterceptionChain.invokeNext(AbstractInterceptionChain.java:124) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.interceptor.chain.AbstractInterceptionChain.invokeNextInterceptor(AbstractInterceptionChain.java:102) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.executeInterception(InterceptorMethodHandler.java:43) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.interceptor.proxy.InterceptorMethodHandler.invoke(InterceptorMethodHandler.java:36) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.bean.proxy.CombinedInterceptorAndDecoratorStackMethodHandler.invoke(CombinedInterceptorAndDecoratorStackMethodHandler.java:51) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at frol.txobserver.FooService$Proxy$_$$_WeldSubclass.managedFlush(Unknown Source) [f4da9dfa-ba67-446a-abe8-e5172fa8d5f3.jar:]
          at frol.txobserver.TxObserverTest.error_during_managed_flush(TxObserverTest.java:44) [f4da9dfa-ba67-446a-abe8-e5172fa8d5f3.jar
          ...
      Caused by: java.lang.RuntimeException: java.lang.IllegalStateException: ARJUNA016082: Synchronizations are not allowed! Transaction status isActionStatus.RUNNING
          at org.jboss.as.weld.services.bootstrap.WeldTransactionServices.registerSynchronization(WeldTransactionServices.java:85) [wildfly-weld-8.2.0.Final.jar:8.2.0.Final]
          at org.jboss.weld.event.TransactionalObserverNotifier.deferNotification(TransactionalObserverNotifier.java:67) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.event.TransactionalObserverNotifier.notifyObserver(TransactionalObserverNotifier.java:48) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.event.ObserverNotifier.notifyObservers(ObserverNotifier.java:124) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:117) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:673) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at org.jboss.weld.util.ForwardingBeanManager.fireEvent(ForwardingBeanManager.java:101) [weld-core-impl-2.2.6.Final.jar:2014-10-03 10:05]
          at frol.txobserver.UpdateListener.callback(UpdateListener.java:36) [f4da9dfa-ba67-446a-abe8-e5172fa8d5f3.jar:]
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.8.0_20]
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) [rt.jar:1.8.0_20]
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.8.0_20]
          at java.lang.reflect.Method.invoke(Method.java:483) [rt.jar:1.8.0_20]
          at org.hibernate.jpa.event.internal.jpa.ListenerCallback.performCallback(ListenerCallback.java:49) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.jpa.event.internal.jpa.CallbackRegistryImpl.callback(CallbackRegistryImpl.java:112) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.jpa.event.internal.jpa.CallbackRegistryImpl.preUpdate(CallbackRegistryImpl.java:76) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.jpa.event.internal.core.JpaFlushEntityEventListener.invokeInterceptor(JpaFlushEntityEventListener.java:67) [hibernate-entitymanager-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.event.internal.DefaultFlushEntityEventListener.handleInterception(DefaultFlushEntityEventListener.java:342) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.event.internal.DefaultFlushEntityEventListener.scheduleUpdate(DefaultFlushEntityEventListener.java:293) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:160) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:231) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:102) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:55) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1222) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:425) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorNonTrackingImpl.beforeCompletion(SynchronizationCallbackCoordinatorNonTrackingImpl.java:114) [hibernate-core-4.3.7.Final.jar:4.3.7.Final]
          ... 160 more
      Caused by: java.lang.IllegalStateException: ARJUNA016082: Synchronizations are not allowed! Transaction status isActionStatus.RUNNING
          at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.registerSynchronizationImple(TransactionImple.java:375) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.registerSynchronization(TransactionImple.java:352) [narayana-jts-jacorb-5.0.0.Final.jar:5.0.0.Final (revision: 9aa71)]
          at org.jboss.as.weld.services.bootstrap.WeldTransactionServices.registerSynchronization(WeldTransactionServices.java:83) [wildfly-weld-8.2.0.Final.jar:8.2.0.Final]
          ... 184 more

      Is this a bug? Should I create a new issue here: https://issues.jboss.org/browse/WFLY?

      Some possibly intresting observations:

      • Non transactional CDI event observer (@Observes(during = TransactionPhase.IN_PROGRESS ...) works!
      • Transactional CDI event observer works well during explicit flush