簡體   English   中英

JPA /休眠關系在一個方向上起作用

[英]JPA/Hibernate relation working in one direction

我的餐桌父母和孩子之間有很多聯系。

這是Parent類中映射此關系的部分:

@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 Child對象和一個定義為parent Parent對象,則在嘗試添加子代時,它可以從父代起作用:

parent.getChildren().add(child);

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

但是,當我嘗試從另一端開始執行此操作時,我想從孩子那里設置setParent。 如果我定義了Set<Parent> parents並且我在Children類中定義了updateParents()方法,並且我有一個從db加載的child定義為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了,我在記住它時遇到了麻煩。

有人可以指出我在做什么錯,以便可以將父母添加到孩子對象中嗎?

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

您可以更改parents以映射相同的表,即刪除mappedBy ,從而有效地使用兩個單向關聯,但是在更新父級和子級時可能會引起問題。

考慮這種情況:

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

現在,您更新A和C。C是否應該還是A的子代? 該信息是矛盾的。

要解決此問題,只有一方負責更新關系,在您的情況下,關系應為A(按其children集)。

在JPA中,您負責管理協會的雙方。 這意味着您必須在關系的一側顯式設置一個字段,並在多側將元素添加到集合中。

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

在為Student添加Course ,您將管理以下關系:

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

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

從關系的反面持久化時,您將以相同的方式管理實體。

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

僅僅因為您在一個實體上插入/更新字段並不意味着Hibernate / JPA將為您自動更新關系的另一端。 堅持這樣不會更新關聯的另一面:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM