JPA: java.lang.StackOverflowError sur l'ajout de la méthode toString dans les classes d'entité
Tout a bien fonctionné jusqu'à ce que j'ai ajouté toSting()
dans mes classes d'entité.
Après j'ai commencer à obtenir l'erreur suivante lors de l'exécution:
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(); }
}
}
}
EDIT: le Code pour les Étudiants de l'entité ajouté
@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 + "]";
}
}
OriginalL'auteur skip | 2014-05-31
Vous devez vous connecter pour publier un commentaire.
Mise à jour basé sur l'addition de l'Élève de la classe
Selon la trace de la pile, votre problème est lié à la
Student.toString()
, voici donc ce qui se passe:Dans
Teacher.toString()
, vous êtes implicitement appel à laStudent.toString()
en plaçant lestudents
membre au sein d'unString
concaténation de déclaration:+ students +
. DansStudent.toString()
le code fait quelque chose de similaire, y compris par lateacher
membre au sein d'unString
concaténation de déclaration.Cela signifie que l'appel soit
Teacher.toString()
ouStudent.toString()
finiront provoquant une boucle sans fin où:Teacher.toString()
appelle implicitementStudent.toString()
, qui à son tour appelle implicitementTeacher.toString()
, qui à son tour appelleStudent.toString()
, qui appelle à son tour...Le 2
.toString()
implémentations de continuer à l'appeler en arrière et en avant, en arrière et en avant, en arrière et en avant, dans une boucle sans fin, qui a fini par les débordements de la pile et les résultats dans unjava.lang.StackOverflowError
.Pour corriger le problème, vous devez supprimer les références implicites à la
.toString()
méthodes des entités. En remplacement, vous pourriez avoirTeacher.toString()
simplement la sortie dulength()
de lastudents
collection et peut-être inclure une liste de l'Student
nom(s). Et dans leStudent.toString()
, il suffit d'inclure leTeacher.name
membre.Student
entité en bas.Juste mis à jour le
toString
méthode dans leGuide
entité à cepublic String toString() { return "Guide [id=" + id + ", staffId=" + staffId + ", name=" + name + ", salary=" + salary + ", students.size()=" + students.size() + "]"; }
. Il a résolu le problème. Je vous remercie.J'ai mis à jour ma réponse basée sur votre addition de la
Student
classe. Mon intuition était correcte et ma réponse devrait vous aider à corriger le problème.OriginalL'auteur Sean Mickey
Entité Enseignant de la Classe ont
toString()
problème:OriginalL'auteur user8300258