java Sping Boot @ManyToMany引发堆栈溢出错误

2vuwiymt  于 2023-03-11  发布在  Java
关注(0)|答案(1)|浏览(155)

我只是想在“学生”和“课程”之间建立一个多对多的关系,我的类和错误的输出如下所示:

public class Course {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;
    String courseName;
    @ManyToMany(mappedBy = "courses")
    List<Student> students;
}
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;
    String userName;
    String password;
    @ManyToMany
    @JoinTable(
            name = "student_courses",
            joinColumns = @JoinColumn(name = "user_id",referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "course_id",referencedColumnName = "id")
    )
    @JsonIgnore
    List<Course> courses;
}

StackOverflowError
如何建立多对多关系而不出现该错误?

wkftcu5l

wkftcu5l1#

toString方法抛出StackOverflowError可能是因为您还试图打印集合。
我想你的Student.toString()看起来像这样:

public String toString() {
  return "Name: " + userName +... + courses.toString();
}

Course.toString()

public String toString() {
  return "Course name: " + coursename + students.toString();
}

当它尝试字符串化Student时,它将触发courses.toString(),即List.toString()。除非您使用Java集合框架之外的实现,否则它应该尝试调用每个元素的toString方法。
由于两个集合在这里是同步的,course1.toString()将调用student1.toString()student1.toString()将调用course1.toString()并导致无限递归循环,从而导致StackOverflowError
要确保不会发生此循环,您可以:
1.不要字符串化关联的集合。
1.提供自定义toString(),它知道何时打印集合,何时不打印集合。
例如:

// Student.java
public String toString() {
  // Don't concat courses.toString() here
  return "Name:" +... ;
}

public String toStringWithCollection() {
  // courses.toString() will invoke student.toString()
  return toString() + courses.toString();
}

现在,如果调用student1.toStringWithCollection(),它应该会打印出您想要的内容(也可能不是)。

相关问题