3 Replies Latest reply on Mar 23, 2009 5:48 PM by skajotde

    Merging an object twice

      Hi,

      I´ve got a strange behaviour:
      If I call entityManager.merge(object) twice I get a OptimisticLockingException or alternatively an EntityExistsException using the embedded JBoss for test purposes.

      Is this the correct behaviour? As far as I knew, I could call merge() multiple time and the underlying implementation decides what to do. For a newly created entity call persist, otherwise re-manage the object or update it´s values. But there is not reason why calling merge multiple times causes an Exception. Or am I wrong?

      Did I misunderstood anything or is this a strange bug in the strange embedded jboss.

      Thanks
      Thomas

        • 1. Re: Merging an object twice
          jaikiran

          Please post the entire exception stacktrace and the relevant piece of code where you are doing this merge.

          embedded jboss


          I have heard many versions of that term embedded :) Which embedded JBoss are you using? Can you point us to a link where you downloaded it from?

          • 2. Re: Merging an object twice

            Okay.

            Here comes more details.

            I use the embedded jboss, that is in the jboss maven repository. Here are the groupId/artifactIds

            org.jboss.embedded:hibernate-all:jar:beta3:test
            org.jboss.embedded:jboss-embedded-all:jar:beta3:test
            org.jboss.embedded:jboss-embedded:jar:beta3:test
            org.jboss.microcontainer:jboss-deployers-client-spi:jar:2.0.0.Beta6:test
            org.jboss.microcontainer:jboss-deployers-core-spi:jar:2.0.0.Beta6:test
            org.jboss.embedded:thirdparty-all:jar:beta3:test
            


            My usage is fairly simple.
            I´ve got a very simple test-case where I simply added merge() a couple of times to see it´s behaviour:

            public void simpleTest() {
             Member aMember = new Member();
             aMember.setMembershipType(MembershipType.ACTIVE);
             getEntityManager().merge(aMember);
             aMember.setMembershipType(MembershipType.HONORARY);
             getEntityManager().merge(aMember);
             try {
             doSomething();
             } catch (Exception ex) {
             aMember.setMembershipType(MembershipType.SPONSOR);
             getEntityManager().merge(aMember);
             }
             getEntityManager().merge(aMember);
             }
            


            If I execute this code, the entity is persisted 4 (!!!) times. I expected that it still is attached to the session and therefor only updates the values.

            If I use an already persisted entity and try to merge it - maybe as follows:

            public void activateMember(Member aMember, Date entryDate) {
             aMember.activate(entryDate);
             getEntityManager().merge(aMember);
             try {
             getMailManager().sendActivationConfirmation(aMember);
             throw new NotificationException("Big badaboom'!");
             } catch (NotificationException ex) {
             String message = String.format("An error occured while sending ActivationConfirmation to '%s': %s", aMember.getEmail(), ex.getMessage());
             LOG.error(message, ex);
             member.addActionLog(new ActionLog(message));
             getEntityManager().merge(member);
             }
             }
            


            If this snippet reaches the second merge, it leads to either an OptimisticLockingException, if using the @Version or an EntityExistsException if I remove this annotation.

            Here comes the stacktrace:

            javax.ejb.EJBTransactionRolledbackException: nested exception is: javax.persistence.OptimisticLockException
            javax.persistence.OptimisticLockException
             at org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:643)
             at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:600)
             at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:237)
             at org.jboss.ejb3.entity.TransactionScopedEntityManager.merge(TransactionScopedEntityManager.java:183)
             at company.members.core.services.memberManager.MemberManagerBean.logAction(MemberManagerBean.java:136)
             at company.members.core.services.memberManager.MemberManagerBean.activateMember(MemberManagerBean.java:125)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:121)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:110)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
             at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:44)
             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:101)
             at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
             at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:126)
             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:64)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:166)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
             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.localInvoke(StatelessContainer.java:249)
             at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:214)
             at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:86)
             at $Proxy85.activateMember(Unknown Source)
             at company.members.core.services.invoiceManager.InvoiceManagerBean.invoicePaid(InvoiceManagerBean.java:74)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:121)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:110)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
             at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:44)
             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:101)
             at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
             at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
             at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:193)
             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:64)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:166)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
             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.localInvoke(StatelessContainer.java:249)
             at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:214)
             at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:86)
             at $Proxy87.invoicePaid(Unknown Source)
             at company.members.test.service.InvoiceManagerTest.testPaidInvoiceForNewMember(InvoiceManagerTest.java:151)
             at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:74)
             at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:92)
             at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
             at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
             at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
            Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [company.members.core.model.
             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:228)
             ... 114 more
            javax.ejb.EJBTransactionRolledbackException: nested exception is: javax.persistence.OptimisticLockException
             at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:91)
             at org.jboss.aspects.tx.TxPolicy.invokeInCallerTx(TxPolicy.java:130)
             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:64)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:166)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
             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.localInvoke(StatelessContainer.java:249)
             at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:214)
             at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:86)
             at $Proxy85.activateMember(Unknown Source)
             at company.members.core.services.invoiceManager.InvoiceManagerBean.invoicePaid(InvoiceManagerBean.java:74)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:121)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:110)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
             at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:44)
             at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:101)
             at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50)
             at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
             at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:47)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
             at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:193)
             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:64)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.tx.NullInterceptor.invoke(NullInterceptor.java:42)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.security.Ejb3AuthenticationInterceptorv2.invoke(Ejb3AuthenticationInterceptorv2.java:166)
             at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
             at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:46)
             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.localInvoke(StatelessContainer.java:249)
             at org.jboss.ejb3.stateless.StatelessContainer.localInvoke(StatelessContainer.java:214)
             at org.jboss.ejb3.stateless.StatelessLocalProxy.invoke(StatelessLocalProxy.java:86)
             at $Proxy87.invoicePaid(Unknown Source)
             at company.members.test.service.InvoiceManagerTest.testPaidInvoiceForNewMember(InvoiceManagerTest.java:151)
             at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:74)
             at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:92)
             at org.apache.maven.surefire.Surefire.run(Surefire.java:180)
             at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
             at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)
            ... Removed 72 stack frames


            So maybe these details might help.

            I´m pretty interested in how to solve this issue!

            Thomas

            • 3. Re: Merging an object twice
              skajotde

              Optymistic exception seems correct because you invoke second merge on old instance and in database is newest.

              I think you should invoke

              aMember = getEntityManager().merge(aMember);