Entrada duplicada 'string1-string2' para a chave 'PRIMARY'
Em um aplicativo Spring MVC usando hibernate e jpa em um banco de dados MySQL, estou recebendo a seguinte mensagem de erro sobre uma entidade filha sempre que tento salvar uma entidade pai que inclui a entidade filha:
Duplicate entry 'string1-string2' for key 'PRIMARY'
Aqui,string1
estring2
consulte as duas partes da chave primária composta da entidade filha.Como eu resolvo esse erro?
Aqui está a maneira como o relacionamento entre as entidades é definido no paiAddress
entidade:
@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;
Aqui está a maneira como o relacionamento é definido na criançaGeneralCode
entidade:
@OneToMany(mappedBy = "use", cascade = {CascadeType.ALL})
private Set<HL7Address> addresses;
O rastreamento completo da pilha pode ser visualizadoclicando neste link.
O código completo para oAddress
entidade pode ser encontradaneste link.
O código completo para oGeneralCode
entidade pode ser lidaneste link.
O código para a classe de chave primária composta pode ser encontradoneste link.
E aBaseEntity
classe que é estendida porAddress
pode ser encontradoneste link.
Eu li muitas postagens nesta mensagem de erro. As respostas para as outras postagens não resolvem minha mensagem de erro e geralmente não tratam do fato de que minha entidade usa umchave primária composta.
EDITAR:O código para persistir o endereço é:
@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);}
}
SEGUNDA EDIÇÃO:Tentei seguir o conselho de @ Ben75, mas o código está travando na linhathis.em.persist(addr.getUse());
. Observe que a cláusula if não se encaixava no meu modelo de objeto real, então alterei a cláusula if abaixo paraif(addr.getUse() != null && addr.getId()==null)
. Aqui está o meu código.
@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);}
}
A parte relevante do HL7Address é agora:
@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;
A parte relevante do HL7GeneralCode é agora:
@OneToMany(mappedBy = "use")
private Set<HL7Address> addresses;
O novo rastreamento de pilha pode ser lidoclicando neste link.
Como posso resolver este erro?
TERCEIRA EDIÇÃO:Segui o conselho de ben75 adicionando o seguinte código ao método de salvar endereço:
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;
}
Infelizmente, ainda estou recebendo o mesmo erro, apesar do rastreamento da pilhaSYSO
indica que o código acima está sendo executado logo antes do aplicativo travar.
Você pode ler o rastreamento de pilha resultanteclicando neste link.