休眠。如何将两个多对多映射到同一个实体

时间:2015-04-12 20:58:46

标签: hibernate

我只是想了解如何在Hibernate中映射以下情况。

有一些课程和一些学生。任何学生都有自己的学习计划,其中包含选修课程和必修课程。

我很容易在数据库世界中对此进行建模。我会有四张桌子:

  1. 课程(身份证,姓名,说明)
  2. 学生(身份证,姓名)
  3. student_course_optional(student_id,course_id)
  4. student_course_required(student_id,course_id)
  5. 但我真的不知道如何用hibernate映射它。

    这是我的初稿:

    @Entity
    public class Student {
    
        private Long id;
        private Long version;
        private String name;
        private List<Course> requiredCourses;
        private List<Course> optionalCourses;
    
        ...
    
        @ManyToMany
        @JoinTable(name="Course")
        public List<Course> getRequiredCourses() {
            return requiredCourses;
        }
    
        @ManyToMany
        @JoinTable(name="Course")
        public List<Course> getOptionalCourses() {
            return optionalCourses;
        }
    }
    
    @Entity
    public class Course {
    
        private Long id;
        private Long version;
        private String name;
        private List<Student> students;
        private List<Student> optionalStudents;
    
        ...
    
        @ManyToMany(mappedBy="requiredCourses")
        public List<Course> getStudents() {
            return requiredCourses;
        }
    
        @ManyToMany(mappedBy="optionalCourses")
        public List<Course> getOptionalStudents() {
            return optionalCourses;
        }
    }
    

    但不知怎的,这对我来说很奇怪。或者这是正确的吗?

2 个答案:

答案 0 :(得分:1)

示例实现可以使用中间实体,例如StudyPlan,其充当UML association class。这样的实体包括:

  • StudyPlanId class
  • 表示的复合主键
  • studentcourse字段代表的外键(在JPA术语中,这是派生标识符
  • optional字段表示的其他状态(它允许区分必需和可选课程)
@Entity
@IdClass(StudyPlanId.class)
public class StudyPlan {
    @Id
    @ManyToOne
    private Student student;

    @Id
    @ManyToOne
    private Course course;

    private boolean optional;
    ...
}
public class StudyPlanId implements Serializable {
    private int course;
    private int student;

    @Override
    public int hashCode() { ... }
    @Override
    public boolean equals(Object obj) { ... }
    ... 
}
@Entity
public class Student {
    @Id
    private int id;

    @OneToMany(mappedBy = "student")
    private Collection<StudyPlan> plan;

    private String name;
    ...
}
@Entity
public class Course {
    @Id
    private int id;

    @OneToMany(mappedBy = "course")
    private Collection<StudyPlan> plan;

    private String name;
    private String description;
    ...     
}

上述实体模型将产生以下数据模型:

Student            StudyPlan            Course
===============    =================    ===============
id           PK    student_id  FK PK    id           PK
name               course_id   FK PK    name      
                   optional             description

答案 1 :(得分:0)

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "student_course_required", joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "course_id", referencedColumnName = "id"))
private List<Course> requiredCourses= new ArrayList<Course>();

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "student_course_optional", joinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "course_id", referencedColumnName = "id"))
private List<Course> optionalCourses= new ArrayList<Course>();

Public Class Student需要更改代码。

 @ManyToMany(fetch = FetchType.EAGER)
 @JoinTable(name = "student_course_required", joinColumns = @JoinColumn(name = "course_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"))
 private List<Student> requiredStudents= new ArrayList<Student>();

 @ManyToMany(fetch = FetchType.EAGER)
 @JoinTable(name = "student_course_optional", joinColumns = @JoinColumn(name = "course_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "id"))
 private List<Student> optionalStudents= new ArrayList<Student>();

public Class Course需要更改代码。 我认为这可以解决你的问题。