3 Replies Latest reply on Dec 4, 2006 7:38 AM by M R

    @PrePersist @PreUpdate within @AroundInvoke results in call-

    M R Newbie

      I have a stateless sessionBean defined using an interceptor on a businessMethod as well as a entityBean with a listener.

      @Stateless
      @TransactionAttribute(TransactionAttributeType.REQUIRED)
      public class MyStatelessSessionBean {
       ...
       @Interceptors(MyInteceptor.class)
       public Object myPersistMethod(MyEntityObject myEntity) {
       ...
       // using an injected entityManager
       return entitymanger.merge(myEntity)
       ...
       }
      }
      
      public class MyInteceptor {
       @AroundInvoke
       public Object doInteception(InvocationContext context) throws Exception {
       try {
       System.out.println("before proceed");
       return context.proceed();
       } finally {
       System.out.println("after proceed");
       }
       }
      
      @Entity
      @EntityListeners(MyEntityListener.class)
      public class MyEntity {
       ...
       // some attributes / setters an getters ...
       ...
      }
      
      public class MyEntityListener {
       @PrePersist
       public void prePersit(Object entity) {
       System.out.println("prePersist entity");
       }
      
       @PreUpdate
       public void preUpdate(Object entity) {
       System.out.println("preUpdate entity");
       }
      }
      
      


      calling the business-Method from a client twice with the same entity results in different call-stacks:

      ======= CREATING THE ENTITY with myEntity = service.myPersistMethod(myEntity) ==============
      INFO [STDOUT] before proceed
      INFO [STDOUT] prePersist entity
      INFO [STDOUT] after proceed
      
      ...
      
      ======= UPDATING THE ENTITY with myEntity = service.myPersistMethod(myEntity) ==============
      INFO [STDOUT] before proceed
      INFO [STDOUT] after proceed
      INFO [STDOUT] preUpdate entity
      
      


      the first output is as expected, but the second isn't what I was expecting, because there is now way for the interceptor to get some information about possible updates within the entity-callbacks ...

      Is this behaviour anywhere defined ? Can I assume any calling order in combination of Interceptors and callbackhandlers within a transaction - or is it explicitly undefined ...

      Thx for any help ---

      wbr


        • 1. Re: @PrePersist@PreUpdate within @AroundInvoke call-tree err
          M R Newbie

          ==> further investigations showed that this happens in EJB3-RC8 as well as EJB3-RC9 !!

          - any ideas ?

          thx

          • 2. Re: @PrePersist @PreUpdate within @AroundInvoke results in c
            Robert Mlekus Newbie

            Hi,

            according to the specification (Ejb-3_0-spec-persistence.pdf chapter 3.5.2) the behaviour of @PrePersist and @PreUpdate may be different.

            in short words (trying to keep the meaning correct)

            @PrePersist and @PreRemove are called before the EntityManger methods persist and remove are executed on the Entity. (leaving out details on merging here! -> thus your code shows "prepersist" before "procedd"

            @PreUpdate is defined differently, though. It occurs before the database operation. The database operation is not exactly scheduled. It can occur due to a flush, or at the end of the transaction -> which is after the try clause
            in your code -> so the ordering of the "preupdate" and "proceed" messages in the result output is correct, but not guaranteed.

            kr.
            Bertl

            • 3. Re: @PrePersist @PreUpdate within @AroundInvoke results in c
              M R Newbie

              but that means that you have NO chance to intercept a business-logic call from a client who is doing an update on an entity that has cascading enabled !!!

              Assume 2 entities e.g. person [1:n] address. You have got a business-method that can be called with person as an attribute only, and the client changed a referenced address-object (remember cascade all is enabled !). So we get a call-back in the pre-update-Method of the address, but we will never know that in the interceptor of the business-logic call, due to the late update-callback (unfortunaltelly we can not use an entityManager in listener-callbacks, but we have also no chance doing this in an interceptor !!!)

              In other words I would have to check weather any address-object has changed myself although I am using ejb3 that is doing these things anyhow ! So why am I using ejb3, if I have to reinvent the wheel ?

              Thx for any feedback