2 Replies Latest reply on Sep 17, 2007 10:47 AM by v.masterov

    Batch removing, conversations and transactions managment

    v.masterov

      I have a question concerning batch entity deletion. I need to delete multiple entities at once, while some of them have references to other entities. When I try to delete a group of entities without any references, the operation is successful. But if at least one of the entities in the batch has references, the transaction is rolled back entirely. What I am trying to do is to delete all the entities without references, while the others (entites in the batch with references) can be left unchanged. I am trying to delete entities using separate transactions for each entity, but still fail. JBoss Seam tutorial mentions manual transaction management through conversation management (using the annotations @Begin(flushMode = FlushModeType.MANUAL) and @End).
      I am trying to perform deletion using the two beans. The first bean implies cycle iteration with all ids and EntityManager is not injected into this bean. A separate deletion is performed within the second bean, this one injects EntityManager. It is not clear how to manage conversations. Both beans are conversation beans. After the first iteration the first bean is performed in the conversation context declared in the second bean, i.e. "join = true". If I declare "join = false" the first iteration returns exception:"java.lang.IllegalStateException: begin method invoked from a long running conversation, try using @Begin(join=true) on method: remove". With "join = true" each next iteration is performed within the same conversation, and as far as I understand in the same transaction. This results in entire rollback of all deletion operations. Please, help me !!! What is the right way to do this ?

      import java.util.*;
      import org.jboss.seam.Component;
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.*;
      import org.jboss.seam.contexts.Contexts;
      import org.jboss.seam.core.Conversation;
      import org.jboss.seam.log.Log;
      
      @Name("entityGroupRemover")
      @Scope(ScopeType.CONVERSATION)
      public class EntityGroupRemover {
      
      
       @Create
       @Begin(id = "groupRemoverConversation", join = true)
       public void remove(Long[] ids, Class entityClass) {
       for (int i = 0; i < ids.length; i++) {
       try {
       log.info("conversationId = " + Conversation.instance().getId());
       SingleEntityRemover remover = (SingleEntityRemover)Component.getInstance("singleEntityRemover",
       ScopeType.CONVERSATION, true);
       remover.removeSingleEntity(ids, entityClass);
       remover.commit();
       } catch(Exception e) {
       e.printStackTrace();
       }
       }
       Conversation.instance().end(true);
       }
      
      
       }
      


      import javax.persistence.EntityManager;
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.*;
      import org.jboss.seam.contexts.Contexts;
      import org.jboss.seam.core.Conversation;
      import org.jboss.seam.core.Messages;
      import org.jboss.seam.log.Log;
      
      @Name("singleEntityRemover")
      @Scope(ScopeType.CONVERSATION)
      public class SingleEntityRemover {
      
       @Logger
       Log log;
      
       @In(value = "entityManager")
       EntityManager em;
      
       @Begin(id = "singleRemoverConversation", flushMode = FlushModeType.MANUAL, join = false, nested = true)
       public void removeSingleEntity(Long id, Class entityClass) {
       log.info("conversationId = " + Conversation.instance().getId());
       Object entity = em.find(entityClass, id);
       em.remove(entity);
       }
      
       @End
       public void commit() throws Exception {
       try {
       em.flush();
       log.info("transaction successed !!!");
       } catch(Exception e) {
       log.info("transaction failed !!!");
       throw e;
       }
       }
      
      }
      


        • 1. Re: Batch removing, conversations and transactions managment
          wschwendt

           

          "v.masterov@gmail.com" wrote:

          I need to delete multiple entities at once, while some of them have references to other entities. When I try to delete a group of entities without any references, the operation is successful. But if at least one of the entities in the batch has references, the transaction is rolled back entirely.


          Have you tried setting the cascade attribute in the annotations that define the relations between your entities? Eg.
          @OneToOne(cascade={CascadeType.REMOVE})
          


          "v.masterov@gmail.com" wrote:

          I am trying to delete entities using separate transactions for each entity, but still fail.


          First of all, I think you're confusing transactions with conversations here.

          Secondly, why do you want to delete each entity within an own nested conversation?

          I assume your intention probably is that if the remove operation for one entity fails, it shouldn't lead to failure of the remove operations for all the other entities.

          Have you really investigated already whether an appropriate cascade remove setting for the relationships between your entities coulnd't solve your problem?


          • 2. Re: Batch removing, conversations and transaction management
            v.masterov

            Unfortunately cascade remove setting is not the way for me, as the entities intended for deletion can be referenced by other entities (i.e. there are references from other entities and the entity under deletion is not aware of such references). For each iteration I need to perform entity deletion attempt. As a result I want the entites without any references to be deleted while the entities with references or referenced by other entities left unchanged. I agree that nested conversation approach is not the best way. If all entities are deleted within a single transaction, there is no way to delete entities without references, if there is at least one entity with references in the batch. That is why I want to implement deletion through separate transactions. And the only way to manage transactions in JBoss AS when working with JBoss Seam is through conversations.