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 :
@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
:
parent.getChildren().add(child);
This updates correctly in db and it saves the entry to parents_children
table.
However when I try to do it from the other end, from children I want to setParent(s). 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 :
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.
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.
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.
Consider this case:
parents
set) You now update A and C. Should C still be a child of A or not? 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).
In JPA your responsible for managing both sides of an association. 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
.
When adding a Course
for a Student
you would manage the relationship such as:
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. 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);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.