I have a many-to-many
relation in a mysql database (Module - <Module_has_Subject> - Subject
). Entites were generated by Eclipse, I added the method add
in both classes. I use JBoss AS7/Hibernate. When I call the persist
method in EJB, I get
org.hibernate.exception.ConstraintViolationException: Duplicate entry '3' for key 'PRIMARY'
I know it must be a trivial mistake, but I just don't see it. I went through most related problems here on StackOverflow and RoseIndia (I added cascade
, targetEntity
,...) and still without success. Entities for tables are as such:
Module.java
@Entity
@Table(name="Module")
public class Module implements Serializable {
@Id
@Column(unique=true, nullable=false)
private int idModule;
//bi-directional many-to-many association to Subject
@ManyToMany(mappedBy="modules", fetch=FetchType.EAGER,targetEntity=entity.Subject.class,cascade=CascadeType.ALL)
private List<Subject> subjects;
public void addSubject(Subject subject) {
if(subject.getModules() == null) {
subject.setModules(new ArrayList<Module>());
}
if(getSubjects() == null) {
setSubjects(new ArrayList<Subject>());
}
if (!getSubjects().contains(subject)) {
getSubjects().add(subject);
}
if (!subject.getModules().contains(this)) {
subject.getModules().add(this);
}
}
...}
Subject.java
@Entity
@Table(name="Subject")
public class Subject implements Serializable {
@Id
@Column(unique=true, nullable=false)
private int idSubject;
//bi-directional many-to-many association to Module
@ManyToMany(fetch=FetchType.EAGER, targetEntity=entity.Module.class,cascade=CascadeType.ALL)
@JoinTable(
name="Module_has_Subject"
, joinColumns={
@JoinColumn(name="Subject_idSubject", nullable=false, referencedColumnName="idSubject")
}
, inverseJoinColumns={
@JoinColumn(name="Module_idModule", nullable=false, referencedColumnName="idModule")
}
)
private List<Module> modules;
public void addModule(Module module) {
if(getModules() == null) {
setModules(new ArrayList<Module>());
}
if(module.getSubjects() == null) {
module.setSubjects(new ArrayList<Subject>());
}
if (!getModules().contains(module)) {
getModules().add(module);
}
if (!module.getSubjects().contains(this)) {
module.getSubjects().add(this);
}
}
...}
SubjectEJB.java
...
Subject subject = new Subject();
for(Module module : subjectModules) {
subject.addModule(module);
}
em.persist(subject);
em.flush();
...
I don't know if you managed to solve your problem yet, but I have just had exactly the same problem.
In my @OneToMany
mapping I used CascadeType.ALL
which resulted in 2 records being saved when I attempted to save the entity. (duplicated data, different ID's)
After scrolling on the web, I found this http://forums.codeguru.com/showthread.php?t=511992, so I changed from CascadeType.ALL
to {CascadeType.PERSIST, CascadeType.MERGE}
, which caused the error you have:
"ConstraintViolationException: Duplicate entry '9-2-2012-05-30' for key 'PlayerId'"
Finally I removed CascadeType.MERGE
and was left with CascadeType.PERSIST
which fixed the duplicate entry error and the duplicated records.
As a point, if I use just CascadeType.MERGE
or just CascadeType.PERSIST
, I get no errors and no duplicated data
Maybe try with CascadeType.MERGE
and CascadeType.PERSIST
, if you get errors, try with just CascadeType.MERGE
.
It is not ideal, but hope it helps.
Chris
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With