繁体   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