Home > Net >  SPRING BOOT infinite recursion
SPRING BOOT infinite recursion

Time:01-12

I have two entitys, Student and Subject. This two class have a many to many relationship. The thing is when i try to link a Subject with Student, not work give me a error. Looks like infinite recursion issue.

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany(mappedBy="students", fetch = FetchType.LAZY)
    @JsonIgnore
    private Set<Subject> subjects;

    @ManyToMany(mappedBy="students")
    @JsonIgnore
    private Set<Exam> exams;

    public boolean addSubject(Subject subject){
        return subjects.add(subject);
    }
}
@Entity
@Data
@NoArgsConstructor
public class Subject {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
            name = "Subjects_Students",
            joinColumns = @JoinColumn(name = "subject_id"),
            inverseJoinColumns = @JoinColumn(name = "student_id"))
    @JsonIgnore
    private Set<Student> students;

    @OneToMany(mappedBy="subject")
    @JsonIgnore
    private Set<Exam> exams;

    @ManyToOne()
    @JoinColumn(name="teacher_id")
    @JsonIgnore
    private Teacher teacher;

    public boolean addStudent(Student student) {
        return students.add(student);
    }
}

the methodo i use int the service is:

@PostMapping("/{studentId}/subject/{subjectId}")
public ResponseEntity<Student> addSubject(@PathVariable Long studentId, @PathVariable Long subjectId ){
    return studentService.addSubject(studentId,subjectId);
}

And the error:

Hibernate: select subjects0_.student_id as student_2_4_0_, subjects0_.subject_id as subject_1_4_0_, subject1_.id as id1_3_1_, subject1_.name as name2_3_1_, subject1_.teacher_id as teacher_3_3_1_, teacher2_.id as id1_5_2_, teacher2_.name as name2_5_2_ from subjects_students subjects0_ inner join subject subject1_ on subjects0_.subject_id=subject1_.id left outer join teacher teacher2_ on subject1_.teacher_id=teacher2_.id where subjects0_.student_id=?

Please help me, this is driving creazy

CodePudding user response:

Try exclude hash code method auto generated by Lombok @Data annotation:

@EqualsAndHashCode(exclude = { "subjects" })
public class Student {

    @ManyToMany(mappedBy="students", fetch = FetchType.LAZY)
    @JsonIgnore
    private Set<Subject> subjects;
}

@EqualsAndHashCode(exclude = { "students" })
public class Subject {

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
            name = "Subjects_Students",
            joinColumns = @JoinColumn(name = "subject_id"),
            inverseJoinColumns = @JoinColumn(name = "student_id"))
    @JsonIgnore
    private Set<Student> students;
}

CodePudding user response:

You can use @JsonIgnoreProperties({<entity_class_name>}) to skip the recursive call.

On student class

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@JsonIgnoreProperties({"Subject"})
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany(mappedBy="students", fetch = FetchType.LAZY)
    @JsonIgnore
    private Set<Subject> subjects;

    @ManyToMany(mappedBy="students")
    @JsonIgnore
    private Set<Exam> exams;

    public boolean addSubject(Subject subject){
        return subjects.add(subject);
    }
}

and on subject class

@Entity
@Data
@NoArgsConstructor
@JsonIgnoreProperties({"Student"})
public class Subject {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
            name = "Subjects_Students",
            joinColumns = @JoinColumn(name = "subject_id"),
            inverseJoinColumns = @JoinColumn(name = "student_id"))
    @JsonIgnore
    private Set<Student> students;

    @OneToMany(mappedBy="subject")
    @JsonIgnore
    private Set<Exam> exams;

    @ManyToOne()
    @JoinColumn(name="teacher_id")
    @JsonIgnore
    private Teacher teacher;

    public boolean addStudent(Student student) {
        return students.add(student);
    }
}
  • Related