假设我们有以下表格
-------------------
| students |
-------------------
| id |
| ... |
-------------------
-------------------
| student_course |
-------------------
| student_id |
| course_id |
| ... |
-------------------
-------------------
| courses |
-------------------
| id |
| ... |
-------------------
从本质上讲,学生与课程之间存在多对多的关系。我不必使用@ManyToMany
和@JoinTable
来将联接表映射为一个实体本身,而是使用student_id和course_id作为组合主键。连接表中还需要维护一些其他审核数据。
我已经尝试过像这样映射这种关系。
学生
@Entity
@Table(name = "students")
public class Student implements Serializable {
// Id and other fields
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL, orphanRemoval = true)
private List<StudentCourse> studentCourses = new ArrayList<>();
public void removeAllAssignedCourses() {
for (int i=0; i < studentCourses.size(); i++) {
removeAssignedCourse(studentCourses.get(i));
i--;
}
}
public void addAssignedCourse(Course course) {
if (studentCourses.contains(studentCourse))
return;
StudentCourse studentCourse = new StudentCourse(this, course);
studentCourses.add(studentCourse);
course.getStudentCourses().add(studentCourse);
}
public void removeAssignedCourse(Course course) {
Iterator<StudentCourse> iterator = studentCourses.iterator();
while (iterator.hasNext()) {
StudentCourse studentCourse = iterator.next();
if (studentCourse.getStudent().equals(this) && studentCourse.getCourse().equals(course)) {
iterator.remove();
course.getStudentCourses().remove(studentCourse);
studentCourse.setStudent(null);
studentCourse.setCourse(null);
}
}
}
//getters setters equals and hashcode
}
课程
@Entity
@Table(name = "courses")
public class Course implements Serializable {
// Id and other fields
@OneToMany(mappedBy = "course", cascade = CascadeType.ALL, orphanRemoval = true)
private List<StudentCourse> studentCourses = new ArrayList<>();
//getters setters equals and hashcode
}
要映射student_course
表,我需要以下内容
StudentCourseId
@Embeddable
public class StudentCourseId implements Serializable {
@Column(name = "student_id")
private UUID studentId;
@Column(name = "student_id")
private UUID courseId;
//getters and setters and equals and hashcode
}
学生课程
@Entity
@Table(name = "student_course")
public class StudentCourse implements Serializable {
@EmbeddedId
private StudentCourseId id;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("STUDENT_ID")
@JoinColumn(name = "STUDENT_ID")
private Student student;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("COURSE_ID")
@JoinColumn(name = "COURSE_ID")
private Course course;
public StudentCourse(Student student, Course course) {
this.student = student;
this.course = course;
this.id = new StudentCourseId(student.getId(), course.getId());
}
// getters, setters, equals and hashcode
}
添加关系时,这似乎很好,我可以很高兴地创建一个新学生,然后保持他/她的学生/课程关系
Course course = new Course("math");
course = courseRepository.save(course);
Student student = new Student("paul");
student = studentRepository.save(student);
student.addAssignedCourse(math);
student = studentRepository.save(student);
但是,如果我希望这样,那就从学生那儿删除所有课程并分配一些新课程
student.removeAllAssignedCourses();
student = studentRepository.save(student);
我收到类似于以下内容的异常
由以下原因引起:org.hibernate.HibernateException:请勿更改 引用启用了delete-orphan的集合: com.example.Student.student课程
这似乎是由于我的removeAssignedCourse
方法中的以下原因
course.getStudentCourses().remove(studentCourse);
但是,对此进行注释会导致进一步的问题,因为该课程仍然引用了StudentCourse。维持这种关系的最佳方法是什么?