2012-04-30 4 views
3

J'ai une relation many-to-many dans la base de données mysql (Module - < Module_has_Subject> - Objet). Les entités ont été générées par Eclipse, j'ai ajouté la méthode 'add' dans les deux classes. J'utilise JBoss AS7/Hibernate. Lorsque j'appelle la méthode persist dans EJB, j'obtiens org.hibernate.exception.ConstraintViolationException: Dupliquer l'entrée '3' pour la clé 'PRIMARY'. Je sais que ce doit être une erreur triviale, mais je ne le vois tout simplement pas. Je suis passé par la plupart des problèmes liés ici sur Stackoverflow et Roseindia (j'ai ajouté cascade, targetEntity, ...) et toujours sans succès. Les entités pour les tables sont en tant que telles:Entrée en double de la clé 'PRIMARY' dans JPA/Hibernate

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(); 
... 
+0

persistez-vous les données deux fois? –

+0

J'espère pas: P. J'ai fait tout par le code existant pour la cartographie bidirectionnelle (http://www.java2s.com/Code/Java/JPA/ManyToManyBidirectionalMapping.htm). Ce sont les méthodes addModule et addSubject. Si je comprends bien, il appartient au développeur de prendre soin de faire toutes les entités et références à eux, avant qu'ils ne soient persistés. Dans ce cas, par exemple, lorsque vous affectez des modules à un objet (ou vice versa), vous devez également renvoyer des références dans les entités de module à l'objet Objet. Et si Module est déjà persistant, vous devez toujours lui donner une référence à Sujet, c'est-à-dire par rapport à lui, n'est-ce pas? – MinastionLyg

Répondre

5

Je ne sais pas si vous avez réussi à résoudre votre problème pour le moment, mais je viens d'avoir exactement le même problème.

Dans mon mappage @OneToMany, j'ai utilisé Cascade.ALL, ce qui a entraîné l'enregistrement de 2 enregistrements lorsque j'ai tenté de sauvegarder l'entité. (Données dupliquées, différentes de ID)

Après avoir fait défiler sur le web, je trouve ce http://forums.codeguru.com/showthread.php?t=511992, donc je changé de CascadeType.ALL à {CascadeType.PERSIST, CascadeType.MERGE}, ce qui a causé l'erreur que vous avez « ConstraintViolationException: double entrée '9-2-2012-05-30' pour la clé 'PlayerId' "

Enfin, j'ai supprimé Cascade.MERGE et est resté avec CascadeType.PERSIST qui a corrigé l'erreur d'entrée en double et les enregistrements dupliqués.

Comme point, si je viens d'utiliser Merge ou juste persistez, je reçois aucune erreur et aucune donnée dupliqués

Peut-être essayer avec MERGE et PERSISTENT, si vous obtenez des erreurs, essayez avec juste Merge.

Ce n'est pas idéal, mais j'espère que cela aidera.

Chris

Questions connexes