java - 休眠中ManyToMany关系的无限递归
问题描述
我正在尝试在Java中创建一个双向ManyToMany模型,我在数据库中插入数据没有问题,但是当我尝试从这些表中检索数据时,它开始无限递归......我尝试了这个baeldung教程中的解决方案, 但没有其中一些对我有用,也许我将注释放在错误的位置。
我需要的是找到 1 名学生以及分配给给定学生的课程是什么。
数据库
楷模
学生
@Component
@Entity
@Table(name="Student")
public class Student {
@Id
@Column(name="student_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name="student_name")
private String name;
@Column(name="student_address")
private String address;
@Column(name="student_email")
private String email;
@Column(name="student_username")
private String username;
@Column(name="student_password")
private String password;
@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy="pk.student")
private Set<StudentCourse> studentCourses;
public Student() {
studentCourses = new HashSet<StudentCourse>(0);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<StudentCourse> getCourses() {
return studentCourses;
}
public void setCourses(Set<StudentCourse> studentCourses) {
this.studentCourses = studentCourses;
}
}
课程
@Component
@Entity
@Table(name="Course")
public class Course {
@Id
@Column(name="course_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name="course_name")
private String name;
@Column(name="course_schedule")
private String schedule;
@ManyToOne
@JoinColumn(name = "teacher_id")
private Teacher teacher;
@JsonBackReference
@OneToMany(fetch = FetchType.LAZY, mappedBy="pk.course")
private Set<StudentCourse> studentCourses = new HashSet<StudentCourse>(0);
public Course() {
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSchedule() {
return schedule;
}
public void setSchedule(String schedule) {
this.schedule = schedule;
}
public Set<StudentCourse> getStudentCourses() {
return studentCourses;
}
public void setStudentCourses(Set<StudentCourse> studentCourses) {
this.studentCourses = studentCourses;
}
}
学生课程
@Component
@Entity
@Table(name="Student_Course")
@AssociationOverrides({
@AssociationOverride(name = "pk.student",
joinColumns = @JoinColumn(name = "student_id")),
@AssociationOverride(name = "pk.course",
joinColumns = @JoinColumn(name = "course_id")) })
public class StudentCourse implements java.io.Serializable {
@EmbeddedId
private StudentCourseId pk = new StudentCourseId();
public StudentCourseId getPk() {
return pk;
}
public void setPk(StudentCourseId pk) {
this.pk = pk;
}
@Transient
public Student getStudent() {
return getPk().getStudent();
}
public void setStudent(Student student) {
getPk().setStudent(student);
}
@Transient
public Course getCourse() {
return getPk().getCourse();
}
public void setCourse(Course course) {
getPk().setCourse(course);
}
}
学生课程编号
@Embeddable
public class StudentCourseId implements java.io.Serializable {
@ManyToOne
private Student student;
@ManyToOne
private Course course;
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
StudentCourseId that = (StudentCourseId) o;
if (student != null ? !student.equals(that.student) : that.student != null) return false;
if (course != null ? !course.equals(that.course) : that.course != null)
return false;
return true;
}
public int hashCode() {
int result;
result = (student != null ? student.hashCode() : 0);
result = 31 * result + (course != null ? course.hashCode() : 0);
return result;
}
}
服务
//find a student by its ID
public Optional<Student> getStudentById(Long studentID) throws SQLException{
return studentRepo.findById(studentID);
}
控制器
//find a student by its ID
@GetMapping("/findStudent/{studentID}")
public ResponseEntity<?> getStudentById(@PathVariable Long studentID){
student = sts.getStudentById(studentID).orElse(new Student());
return new ResponseEntity<>(student, HttpStatus.OK);
}
我的 Json 响应
在“studentCourses”下,我希望我有这个学生被分配到的课程列表,但我得到的只是同一个学生的无限递归......
提前致谢。
解决方案
让它工作@JsonIdentityInfo
,并没有改变类之间的关系。
课程
@Component
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@Entity
@Table(name="Course")
public class Course {
@Id
@Column(name="course_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name="course_name")
private String name;
@Column(name="course_schedule")
private String schedule;
@ManyToOne
@JoinColumn(name = "teacher_id")
private Teacher teacher;
@OneToMany(fetch = FetchType.LAZY, mappedBy="pk.course")
private Set<StudentCourse> studentCourses = new HashSet<StudentCourse>(0);
public Course() {
}
/*
@ManyToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name="teacher_id")
public Teacher getTeacher() {
return teacher;
}
*/
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSchedule() {
return schedule;
}
public void setSchedule(String schedule) {
this.schedule = schedule;
}
public Set<StudentCourse> getStudentCourses() {
return studentCourses;
}
public void setStudentCourses(Set<StudentCourse> studentCourses) {
this.studentCourses = studentCourses;
}
}
学生
@Component
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property="id")
@Entity
@Table(name="Student")
public class Student {
@Id
@Column(name="student_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name="student_name")
private String name;
@Column(name="student_address")
private String address;
@Column(name="student_email")
private String email;
@Column(name="student_username")
private String username;
@Column(name="student_password")
private String password;
@OneToMany(fetch = FetchType.LAZY, mappedBy="pk.student")
private Set<StudentCourse> studentCourses;
public Student() {
studentCourses = new HashSet<StudentCourse>(0);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<StudentCourse> getCourses() {
return studentCourses;
}
public void setCourses(Set<StudentCourse> studentCourses) {
this.studentCourses = studentCourses;
}
}
推荐阅读
- kotlin - Single.fromCallable 未正确实现
- audio - 在树莓派 Windows IOT 上录制 mp3 格式的音频文件
- java - 使用 2D Array 切换状态而不使用 Switchcase
- c# - C# - 过时的东西,将其标记为错误,但仍然可以访问它?
- c# - 构建用于过滤字典列表的 lambda 表达式
- python - 如何从上级目录导入脚本
- asp.net-core - 我要添加哪些路由,以便我可以将 MVC 和 Web API 与默认 Get 和附加操作混合使用?
- javascript - 如何使用一组选项过滤列表
- javascript - 删除数组中的所有`null`而不在JS中循环
- javascript - 当使用 'onchange' 事件优于 'onsubmit' 事件时