2012-04-30 78 views
3

我在mysql數據庫中有多對多的關係(模塊 - < Module_has_Subject> - Subject)。實體由Eclipse生成,我在兩個類中都添加了方法'add'。我使用JBoss AS7/Hibernate。當我在EJB中調用persist方法時,我得到org.hibernate.exception.ConstraintViolationException:重複鍵'PRIMARY'的條目'3'。我知道這肯定是一個微不足道的錯誤,但我只是看不到它。我在Stackoverflow和roseindia(我添加了cascade,targetEntity,...)這裏經歷了大部分相關的問題,但仍然沒有成功。爲表實體是這樣:在JPA /休眠中鍵'PRIMARY'的重複條目

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

你是否堅持數據兩次? –

+0

我希望不是:P。我通過現有的雙向映射代碼創建了所有內容(http://www.java2s.com/Code/Java/JPA/ManyToManyBidirectionalMapping.htm)。這是方法addModule和addSubject。據我瞭解,開發人員需要在所有實體和參考資料被持續保存之前處理。在這種情況下,例如,當您將模塊分配給主題(反之亦然)時,您還必須將模塊實體中的引用返回到主題對象。而且,如果Module已經持續存在,你還是必須給他提供Subject,這與他有關,對吧? – MinastionLyg

回答

5

我不知道,如果你設法解決你的問題,但我剛剛有完全相同的問題。

在我的@OneToMany映射中,我使用了Cascade.ALL,當我試圖保存實體時,導致2個記錄被保存。 (重複數據,不同的ID)

滾動在網絡上後,我發現這個http://forums.codeguru.com/showthread.php?t=511992,所以我從CascadeType.ALL改爲{CascadeType.PERSIST,CascadeType.MERGE},這引起了錯誤,你有「ConstraintViolationException:重複條目'9-2-2012-05-30'爲關鍵'PlayerId'「

最後我刪除了Cascade.MERGE,並留下了CascadeType.PERSIST,它修復了重複條目錯誤和重複記錄。

作爲一個點,如果我用剛剛合併或只是堅持下去,我沒有得到任何錯誤和重複數據

也許用MERGE嘗試和堅持下去,如果你得到錯誤,請嘗試使用剛剛合併。

這並不理想,但希望它有幫助。

Chris