hibernate - 如何将 2 个字段映射到同一个多对多关联?
问题描述
有一个 Spring JPA 应用程序:
对于一个用例,我想将所有学生数据读入一组学生,如下面的第一个集合(CourseRepository.findAll()) - 这仅用于读取与课程相关联的学生。
对于第二个用例,我想仅使用学生 UUID 来读取和更新学生集(因为这明显更快,避免了许多连接/级联) - 如下面的第二个集 - 这仅用于添加或删除学生一门课程。
@Entity
@Table(...)
public class Course {
@Id
private UUID id;
@ManyToMany(fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST})
@JoinTable(
schema = "...",
name = "...",
joinColumns = {@JoinColumn(name = "course_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "student_id", referencedColumnName = "id")}
)
private Set<Student> students = new java.util.HashSet<>();
@ManyToMany
@JoinTable(
schema = "...",
name = "...",
joinColumns = {@JoinColumn(name = "course_id", referencedColumnName = "id")},
inverseJoinColumns = {@JoinColumn(name = "student_id", referencedColumnName = "id")}
)
private Set<UUID> students = new java.util.HashSet<>();
...
}
@Entity
@Table(name="student")
public class Student {
@Id
private UUID id;
private String name;
...
}
@Repository
public interface CourseRepository extends JpaRepository<Course, UUID> {}
解决方案
您应该将多对多关联建模为两个一对多关联,因为无论如何这都是您最终需要的。这样,可以通过简单地持久化这个新CourseStudentAssignment
实体来完成分配。
@Entity
public class CourseStudentAssignment {
@EmbeddedId
CourseStudentAssignmentId id;
@ManyToOne(fetch = LAZY)
@MapsId("courseId")
Course course;
@ManyToOne(fetch = LAZY)
@MapsId("studentId")
Student student;
}
@Embeddable
public class CourseStudentAssignmentId {
UUID courseId;
UUID studentId;
}
@Entity
@Table(...)
public class Course {
@Id
private UUID id;
@OneToMany(mappedBy = "course", fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST})
private Set<CourseStudentAssignment> studentAssignments = new java.util.HashSet<>();
}
@Entity
@Table(...)
public class Student {
@Id
private UUID id;
@OneToMany(mappedBy = "student", fetch = FetchType.LAZY, cascade = {CascadeType.DETACH, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.PERSIST})
private Set<CourseStudentAssignment> courseAssignments = new java.util.HashSet<>();
}
推荐阅读
- java - java更新时可以自动更新JRE_HOME吗?
- css - 对齐图像上方和下方的文本
- ios - Swift 中的 AVfoundation - 如何包含多种文件类型
- android - Android View Model 和 Singleton 类之间到底有什么区别
- sql - 如果日期为空,如何使 AFTER INSERT TRIGGER 将日期更改为 getdate()
- regex - 字符集中的正则表达式捕获组 ( ) [ ]
- java - @AuthenticationPrincipal 抛出异常
- javascript - 如何在数组数组中连接数组的字符串属性并在每个数组中创建一个新属性
- docker - 在 Docker 中解析服务器日志?
- c++ - 条件变量“虚假”觉醒