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

问题描述:

我只是试图找出如何在Hibernate中映射下面的情况。休眠。如何将两个多对多映射到同一个实体

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

我很容易在数据库世界中建模。我将有四个表:

  1. 场(ID,名称,描述)
  2. 学生(ID,姓名)
  3. student_course_optional(student_id数据,COURSE_ID)
  4. student_course_required(student_id数据,COURSE_ID)

但我真的不知道如何映射这与休眠。

这里我的第一稿:

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

但不知何故,这看起来奇怪我。或者这是正确的?

+1

是否可以接受你改变数据库模型一点:更换_student_course_optional_和_student_course_required_表与例如_student_course(student_id,course_id,可选)_? – wypieprz

+0

@wypieprz是的,它似乎更好:) – Tima

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

  • StudyPlanId类表示的化合物主键
  • 通过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 

@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需要更改为up代码。

@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需要更改为up代码。 我认为这可以解决你的问题。