Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicate entry for key 'PRIMARY' in JPA/Hibernate

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();
...
like image 783
MinastionLyg Avatar asked Apr 30 '12 08:04

MinastionLyg


1 Answers

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.MERGEand CascadeType.PERSIST, if you get errors, try with just CascadeType.MERGE.

It is not ideal, but hope it helps.

Chris

like image 73
Chris Avatar answered Oct 16 '22 02:10

Chris