休眠。如何将两个多对多映射到同一个实体
问题描述:
我只是试图找出如何在Hibernate中映射下面的情况。休眠。如何将两个多对多映射到同一个实体
有一些课程和一些学生。任何学生都有自己的学习计划,其中包含可选课程和必修课程。
我很容易在数据库世界中建模。我将有四个表:
- 场(ID,名称,描述)
- 学生(ID,姓名)
- student_course_optional(student_id数据,COURSE_ID)
- 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;
}
}
但不知何故,这看起来奇怪我。或者这是正确的?
答
示例实现可以使用中间实体,比如StudyPlan
,其充当UML association class。这样的实体包括:
- 由
StudyPlanId
类表示的化合物主键 - 通过
student
和course
字段表示的外键(在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代码。 我认为这可以解决你的问题。
是否可以接受你改变数据库模型一点:更换_student_course_optional_和_student_course_required_表与例如_student_course(student_id,course_id,可选)_? – wypieprz
@wypieprz是的,它似乎更好:) – Tima