3

我的桌子父母和孩子之间有很多关系。

这是映射此关系的 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,一个父对象定义为parent

parent.getChildren().add(child);

这会在 db 中正确更新,并将条目保存到parents_children表中。

但是,当我尝试从另一端进行操作时,我想从孩子那里设置父母。如果我已经Set<Parent> parents定义并且我updateParents()在我的Children类中定义了方法,并且我从定义为的 db 加载了一个孩子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 了,我很难记住这个。

有人可以向我指出我做错了什么,以便我可以将父母添加到孩子对象中吗?

4

2 回答 2

3

不,你的定义没有错。问题是children关联的拥有方,除非您将子项添加到该集合中,否则数据库将不会更新。

您可以更改parents为映射同一个表,即删除mappedBy并因此有效地使用两个单向关联,但这可能会在更新父母和孩子时导致问题。

考虑这种情况:

  • 对象 A 有孩子 B 和 C
  • 对象 B 有父对象 A
  • 对象 C 没有父对象(A 不在parents集合中)

您现在更新 A 和 C。C 是否仍然是 A 的孩子?信息是矛盾的。

为了解决这个问题,只有一方应该负责更新关系,在你的情况下是 A (通过它的children集合)。

于 2013-10-02T09:07:04.037 回答
0

在 JPA 中,您负责管理协会的双方。这意味着您必须在关系的一侧显式设置一个字段,并在多侧将一个元素添加到集合中。

例如,考虑Student具有字段的实体List<Course>并假设两个实体之间存在双向OneToMany/ManyToOne关系,Student并且Course.

Course为 a添加 a时,Student您将管理关系,例如:

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);
于 2013-10-02T09:08:47.763 回答