Hibernate 多对多休眠反向侧忽略

Hibernate 多对多休眠反向侧忽略,hibernate,jpa-2.0,Hibernate,Jpa 2.0,您好,我正在阅读hibernate文档 多对多关联是使用@ManyToMany逻辑定义的 注释。您还必须描述关联表和 使用@JoinTable注释连接条件。如果协会是 双向,一方必须是所有者,另一方必须是所有者 反向结束(即,在更新关系时将忽略它 关联表中的值): 除了最后一句,我什么都懂 (即,在更新关联表中的关系值时将忽略该值) 这是什么意思?示例?假设您有以下实体: @Entity public class Student { @ManyToMany private Se

您好,我正在阅读hibernate文档

多对多关联是使用@ManyToMany逻辑定义的 注释。您还必须描述关联表和 使用@JoinTable注释连接条件。如果协会是 双向,一方必须是所有者,另一方必须是所有者 反向结束(即,在更新关系时将忽略它 关联表中的值):

除了最后一句,我什么都懂

(即,在更新关联表中的关系值时将忽略该值)


这是什么意思?示例?

假设您有以下实体:

@Entity
public class Student {
    @ManyToMany
    private Set<Course> courses;
    ...
}

@Entity
public class Course {
    @ManyToMany(mappedBy = "courses")
    private Set<Student> students;
    ...
}
Hibernate将在联接表中为student 4和course 3添加一个条目,因为您更新了关联的所有者方(
student.courses

鉴于,如果您执行以下操作:

Course course = session.get(Course.class, 3L);
Student student = session.get(Student.class, 4L);
student.getCourses().add(course);
Course course = session.get(Course.class, 3L);
Student student = session.get(Student.class, 4L);
course.getStudents().add(student);

什么也不会发生,因为uou更新了关联的反面(
course.students
),但忽略了更新所有者方。Hibernate只考虑所有者方面。

要使其双向工作,您需要在实体之间建立两个独立的关系。 这可以由数据库中的一个联接表表示,但默认情况下,它将由两个联接表表示,所以您必须明确表示您想要一个联接表

我将使用前面提到的学生和课程模型来演示它

@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;
    ...
}
@实体
公立班学生{
@许多
@JoinTable(name=“学生\课程”,
joinColumns={@JoinColumn(name=“courses\u id”)},
inverseJoinColumns={@JoinColumn(name=“students\u id”)})
私人设置的课程;
...
}
@实体
公共课{
@许多
@JoinTable(name=“学生\课程”,
joinColumns={@JoinColumn(name=“students_id”)},
inverseJoinColumns={@JoinColumn(name=“courses\u id”)})
私立学校学生;
...
}
在上面的示例中,我们有两个关系,StudentCourse关系的每一方都是一个关系的所有者。 因此,这解决了只在所有者一侧保存对数据库的更改的问题,因为每一侧都是一个关系的所有者

但我们必须记住一个事实,即保存数据后,关系集合不会从数据库中重新加载 所以程序员需要自己处理关系集合。我想说的是,最简单的方法就是 修改关系集合的setter以在实体之间重建循环,如下所示:

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;
}
公共无效设置课程(设置课程){
(课程c:课程){
如果(!c.getStudents().包含(此)){
c、 getStudents()。添加(此);
}
}
本课程=课程;
}
公立学校学生(集合学生){
(学生:学生){
如果(!s.getCourses().包含(此)){
s、 getCourses()。添加(此);
}
}
这个。学生=学生;
}

谢谢!很好的解释。那么唯一的方法就是更新所有者?双方不可能都是所有者,对吗?如果我希望它能双向工作,该怎么办?不可能?是的,您必须更新所有者方。只有一方可以是所有者。没有办法让它双向工作。@JBNizet,那么你对下面的答案怎么说?我说这正是你不应该做的。结果是,你没有一个双向关联,而是有两个不相关的单向关联,都指向同一个联接表,这是不受支持的配置。在更新这些关联时,不能期望Hibernate做正确的事情。