In a Spring MVC application using hibernate and jpa over a MySQL database, I am getting the following error message about a child entity whenever I try to save a parent entity that includes the child entity:
Duplicate entry 'string1-string2' for key 'PRIMARY'
Here, string1
and string2
refer to the two parts of the composite primary key of the child entity. How do I resolve this error?
Here is the way that the relationship between the entities is defined in the parent Address
entity:
@ManyToOne(cascade = { CascadeType.ALL }, fetch=FetchType.EAGER)
@JoinColumns({ @JoinColumn(name = "usecode", referencedColumnName = "code", insertable = false, updatable = false),
@JoinColumn(name = "usecodesystem", referencedColumnName = "codesystem", insertable = false, updatable = false)
})
public HL7GeneralCode use;
Here is the way the relationship is defined in the child GeneralCode
entity:
@OneToMany(mappedBy = "use", cascade = {CascadeType.ALL})
private Set<HL7Address> addresses;
The complete stack trace can be viewed by clicking on this link.
The complete code for the Address
entity can be found at this link.
The complete code for the GeneralCode
entity can be read at this link.
The code for the composite primary key class can be found at this link.
And the BaseEntity
class that is extended by Address
can be found at this link.
I have read many postings on this error message. The answers to the other postings do not resolve my error message, and they generally do not address the fact that my entity uses a composite primary key.
EDIT:
The code for persisting the address is:
@Override
public void savehl7Address(HL7Address addr) {
if ((Integer)addr.getId() == null) {
System.out.println("[[[[[[[[[[[[ about to persist address ]]]]]]]]]]]]]]]]]]]]");
this.em.persist(addr);}
else {
System.out.println("]]]]]]]]]]]]]]]]]] about to merge address [[[[[[[[[[[[[[[[[[[[[");
this.em.merge(addr);}
}
SECOND EDIT:
I tried to follow @Ben75's advice, but the code is crashing at the line this.em.persist(addr.getUse());
. Note that his if clause did not fit my actual object model, so I changed the if clause below to if(addr.getUse() != null && addr.getId()==null)
. Here is my code.
@Override
public void savehl7Address(HL7Address addr) {
if(addr.getUse() != null && addr.getId()==null){
//this next line prints in the stack trace right before the app crashes
System.out.println("about to this.em.persist(addr.getUse());");
//HL7GeneralCode is not persistent yet
this.em.persist(addr.getUse());
//since there is a cascade ALL on the adresses relationship addr is now persistent
return;
}
System.out.println("=========================== inside jpahl7patientrespository.savehl7Address(addr)");
if ((Integer)addr.getId() == null) {
System.out.println("[[[[[[[[[[[[ about to persist address ]]]]]]]]]]]]]]]]]]]]");
this.em.persist(addr);}
else {
System.out.println("]]]]]]]]]]]]]]]]]] about to merge address [[[[[[[[[[[[[[[[[[[[[");
this.em.merge(addr);}
}
The relevant part of HL7Address is now:
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumns({ @JoinColumn(name = "usecode", referencedColumnName = "code", insertable = false, updatable = false),
@JoinColumn(name = "usecodesystem", referencedColumnName = "codesystem", insertable = false, updatable = false)
})
public HL7GeneralCode use;
The relevant part of HL7GeneralCode is now:
@OneToMany(mappedBy = "use")
private Set<HL7Address> addresses;
The new stack trace can be read by clicking on this link.
How can I resolve this error?
THIRD EDIT:
I followed ben75's advice by adding the following code to the save address method:
if(addr.getUse() != null && !this.em.contains(addr.getUse())){
System.out.println("about to this.em.persist(addr.getUse());");
this.em.persist(addr.getUse());return;
}
Unfortunately, I am still getting the same error despite the fact that the stack trace SYSO
indicates that the above code is running just before the app crashes.
You can read the resulting stack trace by clicking on this link.
See Question&Answers more detail:
os