2013-10-02 32 views
2

我的表格父母和孩子之間有很多關係。JPA /休眠關係在一個方向上工作

這是部分從父類映射這種關係:

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
@JoinTable(name = "parents_children", 
      joinColumns = { @JoinColumn(name = "PARENT_ID", nullable = false, updatable = false) }, 
      inverseJoinColumns = { @JoinColumn(name = "CHILD_ID", nullable = false, updatable = false) }) 
protected Set<Child> children = new HashSet<Child>(); 

這裏是我的孩子班上部分:

@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER, mappedBy = "children") 
protected Set<Parent> parents; 

現在,這個來自父方的作品時,我嘗試添加子項,如果我有一個子對象定義爲child並且一個父對象定義爲parent

parent.getChildren().add(child); 

這會在db中正確更新,並將表項保存到parents_children表中。

但是,當我嘗試從另一端,從孩子我想setParent(s)。如果我有Set<Parent> parents定義,我有我的Children類中定義updateParents()方法,我不得不從數據庫中定義爲child加載一個孩子,我想這一點:

public void updateParents() { 
    Set<Parent> parents = //get this from somewhere 

    child.setParents(parents); 
    update(); 
} 

這樣可不行,我試圖找出爲什麼。它會工作,如果我修改我的方法:

public void updateParents() { 
    Set<Parent> parents = //get this from somewhere 

    for (Parent parent : parents) { 
    parent.getChild().add(this); 
    } 
} 

我的關係定義做錯了嗎?我有一段時間沒有使用Java,並且在記住這一段時遇到了麻煩。

有人可以指出我做錯了什麼,所以我可以將父母添加到兒童對象?

回答

3

不,您的定義沒有任何問題。 問題是,children是關聯的擁有方,除非您將子項添加到該集合,否則數據庫將不會更新。

您可以更改parents來映射相同的表格,即刪除mappedBy,從而有效地使用兩個單向關聯,但是當更新父母和孩子時可能會導致問題。

考慮這種情況:

  • 對象A具有子B和C
  • 對象B具有父甲
  • 對象C沒有父(A不在parents集)

您現在更新A和C. C應該仍然是A的孩子嗎?這些信息是矛盾的。

要解決這個問題,只有一方應該負責更新關係,在你的情況下這將是A(通過它的children集合)。

0

在JPA中,您負責管理關聯的雙方。這意味着您必須在關係的一側明確設置一個字段,並在多方面的集合中添加一個元素。

例如,考慮一個Student實體與字段List<Course>並假定兩個實體,StudentCourse之間存在雙向OneToMany/ManyToOne關係。

當添加CourseStudent,你會管理的關係,如:

Course course = //findFromSomewhere; 
Student student = //findEntity; 

course.setStudent(student); 
student.getCourses().add(course); 

當從這種關係中的另一方堅持,你會管理以同樣的方式的實體。

course.setStudent(student); 
    student.getCourses().add(course); 

僅僅因爲你插入/上一個實體更新字段並不意味着休眠/ JPA會自動更新你的關係的另一面。像這樣堅持不會更新協會的另一端:

//This would fail to add the course to the students list of courses. 
    course.setStudent(student); 
    em.persist(course);