1 Reply Latest reply on Aug 24, 2005 5:05 PM by hsiung

    Problem with 2 one-to-many relations

    hsiung

      I got the following error:
      ERROR [AbstractFlushingEventListener] Could not synchronize database state with session

      The problem occurs when a class A hat 2 one-to-many relationships with a class B.
      NB: there is no problem when the relationships are one-to-one or when there is only 1
      one-to-many relationship or when I do not persist the objects.

      What am I doing wrong?

      Client (sessionbean) code:
      A a = new A();
      B b1 = new B();
      B b2 = new B();
      List r1 = new ArrayList();
      r1.add(b1);
      a.setR1(r1);
      List r2 = new ArrayList();
      r2.add(b2);
      a.setR2(r2);
      entityManager.persist(a);
      a.print();

      /*
      * Class A
      */
      package com.ideartis.ejb3;

      import java.util.List;

      import javax.persistence.CascadeType;
      import javax.persistence.Entity;
      import javax.persistence.FetchType;
      import javax.persistence.GeneratorType;
      import javax.persistence.Id;
      import javax.persistence.OneToMany;
      import javax.persistence.OneToOne;

      @Entity
      public class A {
      private Long id;
      private List r1;
      private List r2;

      @Id(generate = GeneratorType.IDENTITY)
      public Long getId() {
      return id;
      }

      public void setId(Long id) {
      this.id = id;
      }

      @OneToMany(cascade = CascadeType.ALL)
      public List getR1() {
      return r1;
      }

      public void setR1(List r1) {
      this.r1 = r1;
      }

      @OneToMany(cascade = CascadeType.ALL)
      public List getR2() {
      return r2;
      }

      public void setR2(List r2) {
      this.r2 = r2;
      }

      public void print() {
      System.out.println("A id" + getId());
      for (int i=0;i<r1.size(); i++) {
      r1.get(i).print();
      }
      for (int i=0;i<r1.size(); i++) {
      r2.get(i).print();
      }
      }
      }

      /*
      * Class B
      */
      package com.ideartis.ejb3;

      import javax.persistence.Entity;
      import javax.persistence.GeneratorType;
      import javax.persistence.Id;

      @Entity
      public class B {
      private Long id;

      @Id(generate = GeneratorType.IDENTITY)
      public Long getId() {
      return id;
      }

      public void setId(Long id) {
      this.id = id;
      }

      public void print() {
      System.out.println("B id" + getId());
      }
      }

      Exception Stacktrace:
      [java] Exception in thread "main" java.lang.RuntimeException: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=ocean/84, BranchQual=, localId=84] status=STATUS_NO_TRANSACTION; - nested throwable: (org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update)
      [java] at org.jboss.aspects.tx.TxPolicy.handleEndTransactionException(TxPolicy.java:185)
      [java] at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:167)
      [java] at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:74)
      [java] at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:134)
      [java] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:88)
      [java] at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:72)
      [java] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:88)
      [java] at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:63)
      [java] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:88)
      [java] at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:93)
      [java] at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:88)
      [java] at org.jboss.ejb3.stateful.StatefulContainer.dynamicInvoke(StatefulContainer.java:179)
      [java] at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:107)
      [java] at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:69)
      [java] at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:325)
      [java] at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:201)
      [java] at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:259)
      [java] at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:327)
      [java] at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:147)
      [java] Caused by: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=ocean/84, BranchQual=, localId=84] status=STATUS_NO_TRANSACTION; - nested throwable: (org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update)
      [java] at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:354)
      [java] at org.jboss.aspects.tx.TxPolicy.endTransaction(TxPolicy.java:162)
      [java] ... 17 more
      [java] Caused by: org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
      [java] at org.hibernate.exception.ErrorCodeConverter.handledNonSpecificException(ErrorCodeConverter.java:92)
      [java] at org.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:80)
      [java] at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
      [java] at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:181)
      [java] at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:74)
      [java] at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:69)
      [java] at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:150)
      [java] at org.hibernate.persister.collection.AbstractCollectionPersister.recreate(AbstractCollectionPersister.java:916)
      [java] at org.hibernate.action.CollectionRecreateAction.execute(CollectionRecreateAction.java:26)
      [java] at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
      [java] at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
      [java] at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
      [java] at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:284)
      [java] at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
      [java] at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:736)
      [java] at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:183)
      [java] at org.jboss.ejb3.entity.ManagedEntityManagerFactory$SessionSynchronization.beforeCompletion(ManagedEntityManagerFactory.java:88)
      [java] at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1473)
      [java] at org.jboss.tm.TransactionImpl.beforePrepare(TransactionImpl.java:1092)
      [java] at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:306)
      [java] ... 18 more
      [java] Caused by: java.sql.BatchUpdateException: failed batch
      [java] at org.hsqldb.jdbc.jdbcStatement.executeBatch(Unknown Source)
      [java] at org.hsqldb.jdbc.jdbcPreparedStatement.executeBatch(Unknown Source)
      [java] at org.jboss.resource.adapter.jdbc.WrappedStatement.executeBatch(WrappedStatement.java:701)
      [java] at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:57)
      [java] at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:174)
      [java] ... 34 more
      [java] Java Result: 1

      Alain Hsiung

        • 1. Re: Problem with 2 one-to-many relations
          hsiung

          I found the solution to the problem myself:
          - use 2 different join tables for the 2 relationships.

          @OneToMany(cascade = CascadeType.ALL)
          @JoinTable(table=@Table(name="AB1"))
          public List getR1() {
           return r1;
          }
          
          @OneToMany(cascade = CascadeType.ALL)
          @JoinTable(table=@Table(name="AB2"))
          public List getR2() {
           return r2;
          }
          


          Alain Hsiung