10

您好正在阅读休眠文档。

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html

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

我明白除了最后的一切

(即更新关联表中的关系值时将被忽略)。

这是什么意思?例子?

4

2 回答 2

30

假设您有以下实体:

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

@Entity
public class Course {
    @ManyToMany(mappedBy = "courses")
    private Set<Student> students;
    ...
}

所有者是学生(因为它没有mappedBy属性)。反面是 Course ((因为它有mappedBy属性)。

如果您执行以下操作:

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

Hibernate 将在连接表中添加学生 4 和课程 3 的条目,因为您更新了关联的所有者端 ( student.courses)。

而如果您执行以下操作:

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

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

于 2012-09-23T14:15:20.927 回答
2

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

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

@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;
    ...
}

在上面的示例中,我们有 2 个关系,学生<->课程关系的每一方都是一个关系的所有者。因此,这解决了仅在所有者方保存对数据库的更改的问题,因为每一方都是一个关系的所有者。

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

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;
}
于 2014-01-01T17:12:43.483 回答