5 Replies Latest reply on Oct 31, 2006 1:19 AM by gavin.king

    Weird async/timer related error, collection not processed on

    rdewell

      Well, I understand this is coming out of hibernate. But, I just hadn't seen it before using the previously working code on the new async timer stuff.

      Same code works fine without using the async timer. I.E. just inlining the same method call synchronously works fine. Using the async timer around the same method call, however, I'm getting errors like below, and the txn is rolled back:

      17:19:15,861 ERROR [AssertionFailure] an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
      org.hibernate.AssertionFailure: collection [x.x.Membership.permissionAssoc] was not processed by flush()
       at org.hibernate.engine.CollectionEntry.postFlush(CollectionEntry.java:205)
       at org.hibernate.event.def.AbstractFlushingEventListener.postFlush(AbstractFlushingEventListener.java:333)
       at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:28)
       at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
       at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
       at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:515)
       at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1491)
       at org.jboss.tm.TransactionImpl.beforePrepare(TransactionImpl.java:1110)
       at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:324)
       at org.jboss.tm.TxManager.commit(TxManager.java:240)
       at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:175)
       at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:87)
       at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:197)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
       at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:131)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
       at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
       at org.jboss.ejb3.stateless.StatelessContainer.callTimeout(StatelessContainer.java:150)
       at org.jboss.ejb.txtimer.TimerImpl$TimerTaskImpl.run(TimerImpl.java:524)
       at java.util.TimerThread.mainLoop(Timer.java:512)
       at java.util.TimerThread.run(Timer.java:462)
      


      The collection "permissionAssoc" referenced above is not consistently the collection (on repeated tests) that it references in the flush error. It doesn't seem to matter what collection it is. It's referenced at least 3 other collections on other tests, across various other entity classes.

      Here's permissionAssoc:

      @OneToMany(mappedBy="membership", cascade=CascadeType.ALL, fetch=FetchType.LAZY)
       protected Set<MembershipPermission> getPermissionAssoc() {
       if (permissionAssoc == null) permissionAssoc = new HashSet<MembershipPermission>();
       return permissionAssoc;
       }
       protected void setPermissionAssoc(Set<MembershipPermission> permissionAssoc) {
       this.permissionAssoc = permissionAssoc;
       }
      


      I most definitely do not access the private var "permissionAssoc" directly anywhere in the class.

      Any ideas on where to look / try? Using 4.0.5. Strange that regular Seam use of the same code would work fine, but once it's in a timer it blows up.

      Ryan

        • 1. Re: Weird async/timer related error, collection not processe
          gavin.king

          Are you passing a managed entity to the async method? Code please.

          • 2. Re: Weird async/timer related error, collection not processe
            rdewell

            Code, sure thing:

            @Local
            public interface OrderProcessor {
             @Asynchronous
             public void process(@Duration long startInMS, String id);
            }
            


            @Stateless
            @Name("OrderProcessor")
            @Interceptors(SeamInterceptor.class)
            public class OrderProcessorImpl implements OrderProcessor, Serializable {
             private static final long serialVersionUID = -8591335166721681758L;
             private static final Log LOG = LogFactory.getLog(OrderProcessorImpl.class);
            
             @In(value="bright", create=true)
             private transient EntityManager em;
            
             public void process(long initialStartMS, String id) {
             LOG.info("Processing transaction: " + id);
            
             AcquisitionTransaction acquisition = em.find(AcquisitionTransaction.class, id);
            
             OrderUtil.process(em, acquisition);
            
             LOG.info("Finished processing txn: " + id + " = " + acquisition.getLifecycle());
             }
            }
            


            So obviously there's a bunch of work going on in the static OrderUtil.process method. OrderProcessor.process(String id) is called from a JSF action method on another stateless Seam component.

            If I leave "@Asynchronous" on the interface, and therefore give it to the timer service, it blows up with the flush error, rolls back, etc.

            If I comment out the @Asynchronous on the interface, and therefore just execute this inline with the JSF request, then everything works just as it has been (fine). Transaction commits, no errors, etc.

            Since all I'm doing to make it work / not work is comment / uncomment @Asynchronous, it's almost like there's a difference of environment going on between a Seam / facelets request lifecycle, and a timer environment wtr to hibernate?

            • 3. Re: Weird async/timer related error, collection not processe
              gavin.king

              What happens if you use @PersistenceContext instead of @In to inject the EntityManager?

              • 4. Re: Weird async/timer related error, collection not processe
                rdewell

                Worth a shot -- changed to:

                //@In(value="bright", create=true)
                @PersistenceContext(unitName="bright")
                private transient EntityManager em;
                


                Identical trace thrown unfortunately.

                • 5. Re: Weird async/timer related error, collection not processe
                  gavin.king

                  Try asking Emmanuel about this in the Hibernate forum - it does not seem to be anything to do with Seam. I bet you will be able to reproduce it in an EJB with an @Timeout method.