我正在尝试用Java创建双向ManyToMany模型,在数据库中插入数据没有问题,但是当我尝试从这些表中检索数据时,它将开始无限递归...我尝试了此baeldung tutorial中的解决方案
 但是它们都不对我有用,也许我把注解放错了地方。

我需要找到一名学生,以及分配给该学生的课程是什么。

数据库

java -  hibernate 中多对多关系的无限递归-LMLPHP

楷模

学生

@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回应

java -  hibernate 中多对多关系的无限递归-LMLPHP

我希望在“ 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;
}


}

08-28 02:47