在我的实体类中添加toSting()
之前,一切正常。
之后我开始在运行时收到以下错误:
Exception in thread "main" java.lang.StackOverflowError
at java.lang.AbstractStringBuilder.append(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at java.lang.StringBuilder.<init>(Unknown Source)
at entity.Guide.toString(Guide.java:51)
at java.lang.String.valueOf(Unknown Source)
at java.lang.StringBuilder.append(Unknown Source)
at entity.Student.toString(Student.java:45)
...
@Entity
public class Teacher {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
@OneToMany(mappedBy="teacher", cascade={CascadeType.PERSIST})
private Set<Student> students = new HashSet<Student>();
public Teacher() {}
public Teacher(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void addStudent(Student student) {
students.add(student);
student.setTeacher(this);
}
@Override
public String toString() {
return "Teacher[id=" + id + ", name=" + name
+ ", students=" + students + "]";
}
}
public class SnafuClient {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("snafu");
EntityManager em = emf.createEntityManager();
EntityTransaction txn = em.getTransaction();
try {
txn.begin();
Query query = em.createQuery("select teacher from Teacher teacher");
List<Teacher> teachers = query.getResultList();
for (Teacher teacher: teachers) {
System.out.println(teacher);
}
txn.commit();
} catch(Exception e) {
if(txn != null) { txn.rollback(); }
e.printStackTrace();
} finally {
if(em != null) { em.close(); }
}
}
}
编辑:添加学生实体的代码
@Entity
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
@JoinColumn(name="teacher_id")
private Teacher teacher;
public Student() {}
public Student(String name, Teacher teacher) {
this.name = name;
this.teacher = teacher;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
@Override
public String toString() {
return "Student [id=" + id +
+ ", name=" + name + ", teacher=" + teacher + "]";
}
}
答案 0 :(得分:15)
根据堆栈跟踪,您的问题与Student.toString()
相关联,所以在这里发生了什么:
在Teacher.toString()
中,您通过将Student.toString()
成员置于students
连接语句String
中隐式调用+ students +
。在Student.toString()
内,代码执行类似操作,方法是将teacher
成员包含在String
连接语句中。
这意味着调用Teacher.toString()
或Student.toString()
将导致永无止境的循环,其中:Teacher.toString()
隐式调用Student.toString()
,后者隐式调用Teacher.toString()
1}},然后调用Student.toString()
,后者又调用...
2个.toString()
实现在一个永无止境的循环中来回,来回,来回,最终溢出堆栈并产生java.lang.StackOverflowError
。
要解决此问题,您应该删除对实体的.toString()
方法的隐式引用。作为替代,您可以Teacher.toString()
只输出length()
集合的students
,并且可以包含Student
名称的列表。在Student.toString()
中,只需添加Teacher.name
成员。
答案 1 :(得分:0)
实体班级教师遇到toString()
问题:
@Entity
public class Teacher {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
@OneToMany(mappedBy="teacher", cascade={CascadeType.PERSIST})
private Set<Student> students = new HashSet<Student>();
public Teacher() {}
public Teacher(String name) {
this.name = name;
}
public Set<Student> getStudents() {
return students;
}
public void addStudent(Student student) {
students.add(student);
student.setTeacher(this);
}
@Override
public String toString() {
return "Teacher[id=" + id + ", name=" + name
+ "]";
}
}
答案 2 :(得分:0)
必须从toString()方法中排除冗余参数。
@ToString.Exclude
一起使用@ExcludeToString
一起使用GL