0 Replies Latest reply on Jun 25, 2012 8:58 AM by ibenjes

    Passing newly created entity from one transaction to another

    ibenjes

      Hi,

       

      I've got a long running conversation where I've set the flush mode to MANUAL. Now I have a modal on the page with which you can create a new address. I want this new address to be saved independently of whether the user clicks save or cancel on the main page. So I can't just persist the new entity and flush the transaction as that might flush other changes as well. I can't just use cascades from the main entity to the address book as the user might not save the main entity (or the user decided to create several address book entries for what ever reason which should all be saved).

       

      So in order to do this I call an async method on a helper bean to which I pass the new address book entity (instance of Idable) and an instance of 'EntityHelper' which is used for callbacks. The async method has its own transaction (btw. Idable is an interface that all my entities implement)

       

      {code}

      @Transactional(TransactionPropagationType.REQUIRED)

      @Asynchronous

                public void saveEntity(Idable entity,EntityHelper helper){

                          entityManager.persist(entity);

        entityManager.flush();

                          Events.instance().raiseTransactionSuccessEvent("async.save.singleSaved", helper,entity);

       

                }

      {code}

       

       

       

       

      {code}

      @Observer(value = "async.save.singleSaved")

                public void mapSaved(EntityHelper helper, Idable entity){

        log.info("Event after transaction completion");

                          helper.callback(entity);

                }

      {code}

       

       

      And in EntityHelper:

       

      {code}

      public void callback(Idable entity){

        finished = true;

                          Idable i = (Idable)entityManager.find(entity.getClass(), entity.getEntityId());

        log.info("Entity #0/#1 saved",entity,i);

      }

      {code}

       

       

      Now in the event that is raised after the transaction finished successfully I call the EntityHelper which tries to load the entity. However the entity cannot be found at that moment. If I remember the ID and only load it before I save the main page then it works fine.

       

      I can see from the Database log that the address book entity is inserted and that the transaction is committed. And I can also see that hibernate is trying to load the instance after this (which returns null).

       

      So transaction 1 (for the main bean) is started first. Then transaction 2 for the async stuff is started and committed, transaction 1 is still alive but can't see the stuff committed in transaction 2. Only on a new JSF request (transaction 3 is created) can I see the stuff from transaction 2. Is that normal?