2 Replies Latest reply on Mar 10, 2010 4:23 PM by Martin Kahres

    tranaction problem

    Martin Kahres Newbie


      I have a problem with a tranaction.

      I have a long runnin conversation. Whenever I get into this conversation and edit an AperakValidierungFeld, it only works for the first time. The second time, I get this stack trace:

      Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.rwe.pokos.entity.validation.AperakValidierungFeld#259]
              at org.hibernate.event.def.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:261)
              at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:120)
              at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
              at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
              at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
              at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
              at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:227)
              ... 128 more

      So I think the transaction from the first time is still active. But I don't understand why. The method I call is this one:

              public String saveCurrentFeld()
                      String lResult;


                      Long lID = this.currentFeld.getId();

                      InvalidValue[] lMessages;

                      ClassValidator<AperakValidierungFeld> lValidator =
                              new ClassValidator<AperakValidierungFeld>(AperakValidierungFeld.class);
                      lMessages = lValidator.getInvalidValues(this.currentFeld);

                      int lCount = (lMessages != null ? lMessages.length : 0);
                      if (lCount <= 0)

                              for(AperakValidierungInhalt inhalt: this.currentFeld.getInhalte())
                                      if(inhalt.getId() == null)
                                              inhalt = this.entityManager.merge(inhalt);

                              if (lID == null)
                                      this.currentFeld = this.entityManager.merge(this.currentFeld);

                              lResult = "savedFeld";

                              this.currentFeldId = null;
                              lResult = null;
                      return lResult;

      It is in a Bean with this annotations:

      The @TransactionAttribute should be default by REQUIRED. I tried to change there a lot, but nothing really helped.

      In the saveCurrentFeld-method I have this.update() at the beginning. If I delete this, I can't edit a AperakValidierungFeld by the first time. With the update it works one time and then the exception is thrown. My understanding was, that the transaction should start and commit/stop within this method because of the @TransactionAttribute-setting. This is the only method I call in this conversation, so it can't come from another method. In this method I merge also AperakValidierungInhalt-entities. Can it be, that it starts several transactions because of this?

      I also tried to commit the transactions manually, but on a getTransaction call on the entityManager I get this exception:
      javax.ejb.EJBTransactionRolledbackException: JTA EntityManager cannot access a transactions

      I tried also with nested conversation, but didnt help.

      The entity beans have bi-directional many2one and one2many annotations and have @version fields.

      It would be very nice if someone could help me here.


        • 1. Re: tranaction problem
          Martin Kahres Newbie
          I have read the "15 gotchas in seam" thread point 3 helped me a lot :)

          Do NOT use entityMgr.merge as it gets you into trouble time after time. Use if(bean.getId != null) entityMgr.persist(bean) instead
          • 2. Re: tranaction problem
            Martin Kahres Newbie
            but I think there is a little mistake in the code, it should be like that:

            if(bean.getId == null) entityMgr.persist(bean)

            So I have to persist entities, if they are saved the first time.

            And the second time, seam makes his own updates for this, when I enable @TrasactionAttribute(TransActionAttributeType.REQUIRED)

            Is this right? Maybe this causes the duplicate transactions?