I am using EclipseLink 2.4.1 and JPA 2.0. In my example, I have the following class definitions:
@Entity public class Shepard { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "id") private Long id; @OneToMany(mappedBy = "shepard", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<Sheep> sheeps; public void addSheep(Sheep sheep) { if (sheep != null) { if (sheeps == null) { sheeps = new ArrayList<>(); } if (!sheeps.contains(sheep)) { sheeps.add(sheep); } } } } @Entity public class Sheep { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "name") private String name; @ManyToOne(fetch = FetchType.EAGER, optional = false) @JoinColumn(name="shepard_id") private Shepard shepard; public Sheep(Shepard shepard, String name) { this.shepard = shepard; this.name = name; shepard.addSheep(this); } }
Now when I write the Junit test and do the following. Note that the Sheep constructor calls Shepard.addSheep (Sheep)!
EntityManagerFactory emf = Persistence.createEntityManagerFactory("data"); EnttyManager em = emf.createEntityManager(); Shepard shepard = new Shepard(); // I Persist Shepard em.getTransaction().begin(); em.persist(shepard); em.getTransaction().commit(); // II Persist Tilda Sheep tilda = new Sheep(shepard, "Tilda"); em.getTransaction().begin(); em.persist(tilda); em.getTransaction().commit(); // III Persist Martha via Shepard Sheep martha = new Sheep(shepard, "Martha"); em.getTransaction().begin(); em.merge(shepard); em.getTransaction().commit();
And then do a named query for Sheep's, I get a duplicate entry for "Tilda"!
This does not happen when I code
em.persist(martha);
as the last entity manager access.
Analyzing the debug output, I see that after II there is one Shepard object with [id = 1] and one Sheep object with [id = 1]. Before and after III, Shepard contains two sheep references, earlier with [id = 1 ] for Tilda and [id = null] for Martha. After III, Shepard contains two references of Sheep with [id = 2 ] for Tilda and [id = 3] for Martha.
From the debug output of EclipseLink, I see that III outputs two inserts into the Sheep table. In the database, three Lamb records end with the identifier above.
Next, I get the following error:
[EL Warning]: 2013-06-21 09:53:26.631--UnitOfWork(221387686)--Thread(Thread[main,5,main])--Exception [EclipseLink-7251] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.ValidationException Exception Description: The attribute [id] of class [Sheep] is mapped to a primary key column in the database. Updates are not allowed.
Is this an EclipseLink error? Or what am I doing wrong here?