简体   繁体   English

JPA /休眠关系在一个方向上起作用

[英]JPA/Hibernate relation working in one direction

I've got many to many relation between my tables parents and children. 我的餐桌父母和孩子之间有很多联系。

This is the part from the Parent class which maps this relation : 这是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>();

Here is the part in my Child class : 这是我的儿童班的一部分:

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

Now this works from the parent side when I try to add children, if I had one Child object defined as child and one Parent object defined as parent : 现在,如果我有一个定义为child Child对象和一个定义为parent Parent对象,则在尝试添加子代时,它可以从父代起作用:

parent.getChildren().add(child);

This updates correctly in db and it saves the entry to parents_children table. 这将在db中正确更新,并将条目保存到parents_children表中。

However when I try to do it from the other end, from children I want to setParent(s). 但是,当我尝试从另一端开始执行此操作时,我想从孩子那里设置setParent。 If I had Set<Parent> parents defined and I had updateParents() method defined inside my Children class and I had one child loaded from db defined as child and I tried this : 如果我定义了Set<Parent> parents并且我在Children类中定义了updateParents()方法,并且我有一个从db加载的child定义为child ,那么我可以尝试这样做:

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

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

This will not work and I'm trying to figure out why. 这将无法正常工作,我正在尝试找出原因。 It will work if I modify my method to : 如果我将方法修改为:

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

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

Am I doing something wrong with relation definition? 我在关系定义上做错了吗? I haven't use Java in a while and I'm having trouble with remembering this one. 我已经有一段时间没有使用Java了,我在记住它时遇到了麻烦。

Can someone point out to me what am I doing wrong so I can add parents to children objects? 有人可以指出我在做什么错,以便可以将父母添加到孩子对象中吗?

No, there's nothing wrong with your definition. 不,您的定义没有错。 The problem is that children is the owning side of the association and unless you add the child to that set the database will not be updated. 问题是children是关联的拥有方,除非将子代添加到该集合中,否则不会更新数据库。

You could change parents to map the same table, ie remove the mappedBy and thus effectively use two uni-directional associations, but that might cause problems when parents and children are updated. 您可以更改parents以映射相同的表,即删除mappedBy ,从而有效地使用两个单向关联,但是在更新父级和子级时可能会引起问题。

Consider this case: 考虑这种情况:

  • Object A has children B and C 对象A有孩子B和C
  • Object B has parent A 对象B具有父A
  • Object C has no parent (A is not in the parents set) 对象C没有父级(A不在parents集中)

You now update A and C. Should C still be a child of A or not? 现在,您更新A和C。C是否应该还是A的子代? The information is contradictory. 该信息是矛盾的。

To resolve this, only one side should be responsible for updating the relation, which in your case would be A (by its children set). 要解决此问题,只有一方负责更新关系,在您的情况下,关系应为A(按其children集)。

In JPA your responsible for managing both sides of an association. 在JPA中,您负责管理协会的双方。 This means that you must explicitly set a field on the one side of the relationship and add an element to a collection on the many side. 这意味着您必须在关系的一侧显式设置一个字段,并在多侧将元素添加到集合中。

For example, consider a Student entity with a field List<Course> and assume a bidirectional OneToMany / ManyToOne relationship exists between both entities, Student and Course . 例如,考虑一个具有字段List<Course>Student实体,并假定两个实体StudentCourse之间存在双向的OneToMany / ManyToOne关系。

When adding a Course for a Student you would manage the relationship such as: 在为Student添加Course ,您将管理以下关系:

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

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

When persisting from the inverse side of the relationship you would manage the entities in the same way. 从关系的反面持久化时,您将以相同的方式管理实体。

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

Just because you insert/update a field on one entity does not mean that Hibernate/JPA will automatically update the other side of the relationship for you. 仅仅因为您在一个实体上插入/更新字段并不意味着Hibernate / JPA将为您自动更新关系的另一端。 Persisting like this would not update the other side of the association: 坚持这样不会更新关联的另一面:

   //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