我的父母和孩子之间有很多很多关系。
这是来自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>();
以下是我的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(s)的孩子。如果我已定义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,而且我在记住这个问题上遇到了麻烦。
有人可以向我指出我做错了什么,所以我可以将父母添加到儿童对象中吗?
答案 0 :(得分:3)
不,你的定义没有错。
问题是children
是关联的拥有方,除非您将子项添加到该组,否则数据库将不会更新。
您可以更改parents
以映射同一个表,即删除mappedBy
,从而有效地使用两个单向关联,但这可能会在更新父级和子级时导致问题。
考虑这种情况:
parents
集中)您现在更新A和C. C还应该是A的孩子吗?信息是矛盾的。
要解决此问题,只有一方应负责更新关系,在您的情况下,关系将是A(通过其children
设置)。
答案 1 :(得分:0)
在JPA中,您负责管理协会的双方。这意味着您必须在关系的一侧显式设置一个字段,并将元素添加到多方的集合中。
例如,考虑一个Student
实体,其字段为List<Course>
,并假设两个实体OneToMany
和{之间存在双向ManyToOne
/ Student
关系{1}}。
为Course
添加Course
时,您可以管理以下关系:
Student
当从关系的反面持久化时,您将以相同的方式管理实体。
Course course = //findFromSomewhere;
Student student = //findEntity;
course.setStudent(student);
student.getCourses().add(course);
仅仅因为您在一个实体上插入/更新字段并不意味着Hibernate / JPA会自动为您更新关系的另一面。坚持这样不会更新协会的另一方:
course.setStudent(student);
student.getCourses().add(course);