Is this a bug?
doubledenim Jun 3, 2006 12:54 AMOr 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; } }