users@glassfish.java.net

Bug in TopLink? Persisting new entities with references to pre-existing one

From: <glassfish_at_javadesktop.org>
Date: Mon, 09 Feb 2009 07:04:39 PST

I'm running into a curious problem with object persistence. I have the following objects:

[code]
@Entity ()
public class LClass implements java.io.Serializable {
    private static final long serialVersionUID = 1L;
   
    @OneToOne(cascade=CascadeType.ALL, mappedBy="lClass")
    private CClass cClass;
}


@Entity
public class CClass implements java.io.Serializable {
    private static final long serialVersionUID = 1L;
   
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "cClass")
    @OrderBy("id ASC")
    private Collection<ZClass> zClasses;

    @OneToOne
    @JoinColumn(name = "LClass_ID_fk", nullable = false)
    private LClass lClass;
}


@Entity
public class ZClass implements java.io.Serializable {
    private static final long serialVersionUID = 1L;
   
    @ManyToOne
    @JoinColumn(nullable = false)
    private CClass cClass;
}
[/code]

So, the relationship is:
LClass ==(OneToOne)==> CClass ==(OneToMany)==> ZClass ==(ManyToOne)==> CClass ==(OneToOne)==> LClass


I retrieve an LClass from the persistence layer, and add a new ZClass under by CClass. Then,
using a new EntityManager to save (the one used during the initial retrieval was localized - not
that I think it matters in this case).

When I go to persist, JPA seems to be creating new instances for my alread existing LClass and
CClass objects that are referenced by the newly added ZClass object. Notice that the
hashcodes change for the last record, but the IDs are the same.

(What we have below is for each section: first line is the LClass object and the CClass object it
references. each additional line that begins with ZClass is a ZClass object in the collection,
along with their back-references)

[code]
System.out.println("LClass:(hashcode=" + myLCass.hashCode() + ",id=" + myLCass.getId() + \
          "): CClass:(hashcode=" + myLCass.getCClass().hashCode() + ",id=" + \
          myLCass.getCClass().getId() + ")");

for (ZClass c : myLCass.getCClass().getZClasses()){
     System.out.println("\tZClass:(hashcode=" + c.hashCode() + ",id=" + c.getId() + \
          "): CClass:(hashcode=" + c.getCClass().hashCode() + ",id=" + c.getCClass().getId() + \
          "): LClass:(hashcode=" + c.getCClass().getLClass().hashCode()+ ",id=" + \
          c.getCClass().getLClass().getId() + ")" );
}
[/code]


[b]--- Before EntityManager.merge ---[/b]
[code]
LClass:(hashcode=1707707379,id=8): CClass:(hashcode=318976698,id=6)
      ZClass:(hashcode=2121849234,id=1): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=29273581,id=2): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=205664115,id=4): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=1691190141,id=5): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=1023639839,id=6): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=1714893413,id=null): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
[/code]

[b]myLClass=em.merge(myLClass);[/b]

[b]--- After EntityManager.merge ---[/b]
[code]
LClass:(hashcode=1707707379,id=8): CClass:(hashcode=318976698,id=6)
      ZClass:(hashcode=2121849234,id=1): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=29273581,id=2): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=205664115,id=4): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=1691190141,id=5): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=1023639839,id=6): CClass:(hashcode=318976698,id=6): LClass:(hashcode=1707707379,id=8)
      ZClass:(hashcode=1714893413,id=7): CClass:(hashcode=797868569,id=6): LClass:(hashcode=1958682376,id=8)
[/code]

Is this a bug in TopLink, or is this how referenced object creation is defined in the spec?
[Message sent by forum member 'groverblue' (groverblue)]

http://forums.java.net/jive/thread.jspa?messageID=330839