简体   繁体   English

休眠中多对多关系的无限递归

[英]Infinite Recursion on ManyToMany relationship on hibernate

I am trying to create a bidirectional ManyToMany model in Java, I have no problem inserting data in the database, but when I try to retrieve data from these tables it starts an infinite recursion... I tried the soluitons in this baeldung tutorial but none of them worked for me, maybe I'm placing the annotations in the wrong place.我正在尝试在 Java 中创建一个双向多对多模型,我在数据库中插入数据没有问题,但是当我尝试从这些表中检索数据时,它开始了无限递归......我尝试了这个baeldung 教程中的解决方案,但没有其中一些对我有用,也许我将注释放在错误的位置。

What I need is to find 1 student and what are the courses asigned to the given student.我需要的是找到 1 名学生以及分配给给定学生的课程是什么。

Database数据库

在此处输入图片说明

Models楷模

Student学生

@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;
    }


}

Course课程

@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;
    }


}

StudentCourse学生课程

@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);
    }


}

StudentCourseId学生课程编号

@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;
    }
}

Service服务

//find a student by its ID
public Optional<Student> getStudentById(Long studentID) throws SQLException{

    return studentRepo.findById(studentID);
}

Controller控制器

//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);
}

My Json response我的 Json 回复

在此处输入图片说明

Under "studentCourses" I wish I had the list of courses this student is assigned to, but all I get is the infinite recursion of the same student...在“studentCourses”下,我希望我有这个学生被分配到的课程列表,但我得到的只是同一个学生的无限递归......

Thanks in advance.提前致谢。

Got it to work using @JsonIdentityInfo , didn't change anything in the relationship between classes.使用@JsonIdentityInfo让它工作,没有改变类之间的关系。

Course课程

@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;
    }


}

Student学生

@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;
}


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM