1 Reply Latest reply on Jun 4, 2006 7:03 AM by doubledenim

    Is this a bug?

    doubledenim

      Or am i doing something wrong?

      I brought this up in an earlier post to which no-one has responded so i took some time to create a test project. If anyone wants me to zip it up and send, let me know.


      The problem: lazy initialisation of the many part of a OneToMany always returns an extra record in the array in the form of a null object at the beginning of the PersistentList.

      Variable output

      this= PersistenceManagerBean (id=415)
      id= Integer (id=427)
      a= ClassA (id=435)
       classBs= PersistentList (id=467)
       cachedSize= -1
       directlyAccessible= false
       dirty= false
       initialized= true
       initializing= false
       key= Integer (id=474)
       list= ArrayList<E> (id=481)
       elementData= Object[10] (id=499)
       [0]= null
       [1]= ClassB (id=501)
       [2]= ClassB (id=502)
       [3]= null
       [4]= null
       [5]= null
       [6]= null
       [7]= null
       [8]= null
       [9]= null
       modCount= 3
       size= 3
       operationQueue= null
       owner= ClassA (id=435)
       role= "test.persistence.ClassA.classBs"
       session= SessionImpl (id=488)
       storedSnapshot= ArrayList<E> (id=497)
       id= Integer (id=474)
       name= "main "
      classb= null
      




      Persistence Manager
      package test.persistence.manager;
      
      //import java.util.List;
      
      
      import javax.ejb.Stateless;
      import javax.persistence.PersistenceContext;
      
      import org.jboss.annotation.ejb.RemoteBinding;
      import test.persistence.ClassA;
      import test.persistence.ClassB;
      
      
      
      @RemoteBinding(jndiBinding="PersistenceManagerTest")
      public @Stateless
      class PersistenceManagerBean implements PersistenceManager {
      
       @PersistenceContext(unitName = "ejb3testproject")
       javax.persistence.EntityManager em;
      
      
      
       public ClassA getClassaById(Integer id) {
      
       ClassA a = new ClassA();
       try {
      
       a = (ClassA) em.createQuery(
       "SELECT DISTINCT OBJECT(a)" + "FROM ClassA a "
       + "WHERE a.id = :id")
       .setParameter("id", id)
       .getSingleResult();
      
       }
       catch(Exception e)
       {
       System.out.println(e.getLocalizedMessage());
       }
       for(ClassB classb:a.getClassBs())
       {
       System.out.println(classb.getName());
       }
      
       return a;
       }
      
      
      }
      



      ClassA Entity
      package test.persistence;
      import java.io.Serializable;
      import java.util.List;
      
      import javax.persistence.*;
      
      import org.hibernate.annotations.IndexColumn;
      
      @Entity
      @Table(name="classA")
      public class ClassA implements Serializable{
      
      
       java.lang.String name;
      
       Integer id;
      
       List<ClassB> classBs;
      
      
       @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
       @Column(name="classa_id")
       public java.lang.Integer getId() {
       return id;
       }
      
       public void setId(java.lang.Integer id) {
       this.id = id;
       }
      
       @Column(name="name")
       public java.lang.String getName() {
       return name;
       }
      
       public void setName(java.lang.String name) {
       this.name = name;
       }
      
       @OneToMany(mappedBy="classA")
       @IndexColumn(name="classb_id")
       public List<ClassB> getClassBs() {
       return classBs;
       }
      
       public void setClassBs(List<ClassB> classBs) {
       this.classBs = classBs;
       }
      
      }
      



      ClassB Entity
      package test.persistence;
      import java.io.Serializable;
      import java.util.List;
      
      import javax.persistence.*;
      
       @Entity
       @Table(name="classB")
       public class ClassB implements Serializable{
      
      
       java.lang.String name;
      
       Integer id;
      
       ClassA classA;
      
      
       @ManyToOne(fetch=FetchType.EAGER)
       @JoinColumn(name="classa_id")
       public ClassA getClassA() {
       return classA;
       }
      
       public void setClassA(ClassA classA) {
       this.classA = classA;
       }
      
       @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
       @Column(name="classb_id")
       public java.lang.Integer getId() {
       return id;
       }
      
       public void setId(java.lang.Integer id) {
       this.id = id;
       }
      
       @Column(name="name")
       public java.lang.String getName() {
       return name;
       }
      
       public void setName(java.lang.String name) {
       this.name = name;
       }
      
       }
      


        • 1. Re: Is this a bug?
          doubledenim

          I've figured it out.. The problem is being caused by the use of @IndexColumn. Which leads me to think that it cannot be used. If i get rid of it i end up with a org.hibernate.TransientObjectException.
          Any Ideas of a solution?


          @OneToMany(mappedBy="classA")
          @IndexColumn(name="classb_id")
          public List getClassBs() {
          return classBs;
          }

          org.hibernate.TransientObjectException