In order for it to work in both directions, you need to have two separate connections between your entities. This may be represented by a single join table in the database, but by default it will be represented by two, so you must explicitly say that you want one join table.
I will demonstrate this using the previously mentioned Student and Course model.
@Entity public class Student { @ManyToMany @JoinTable(name = "student_course", joinColumns = {@JoinColumn(name = "courses_id")}, inverseJoinColumns = {@JoinColumn(name = "students_id")}) private Set<Course> courses; ... } @Entity public class Course { @ManyToMany @JoinTable(name = "student_course", joinColumns = {@JoinColumn(name = "students_id")}, inverseJoinColumns = {@JoinColumn(name = "courses_id")}) private Set<Student> students; ... }
In the above example, we have 2 relationships with each side of the Student <Course relationship that owns one relationship. Thus, this solves the problem of saving changes to the database only on the side of the owner, since each side is the owner of one relationship.
But we must bear in mind one fact that after saving the data, the relationship collections will NOT be reloaded from the database, so the programmer needs to process the relationship collections on his own. Having said that, I want to say that the easiest way is to modify the setters for relationship collections in order to rebuild the cycle between such objects:
public void setCourses(Set<Course> courses) { for(Course c : courses) { if (!c.getStudents().contains(this)) { c.getStudents().add(this); } } this.courses = courses; } public void setStudents(Set<Student> students) { for(Student s : students) { if (!s.getCourses().contains(this)){ s.getCourses().add(this); } } this.students = students; }
termil0r
source share