2013-06-19 6 views
7

Ich habe Entitäten User und GrantedRole, die eine bidirektionale Eins-zu-viele-Beziehung haben.JPA/Hibernate bidirektionale viele-zu-eins Ergebnisse in StackOverflowException

Wenn ich versuche, einen GrantedRole zum Set in Benutzer hinzufügen, gibt es keine Ausnahme ausgelöst, aber wenn ich die Variablen für den Benutzer und GrantedRole Objekt debuggen haben eine Beschreibung, die

com.sun.jdi.InvocationException occurred invoking method.

die verschiedenen Felder liest für die Variablen können während des Debuggens gelesen werden, aber wenn ich das Rollenfeld in Benutzer oder das Benutzerfeld in GrantedRole auswähle, bekomme ich die gleiche Beschreibung wie oben. Als ich in das Set von GrantedRole in Benutzer gehen, finde ich schließlich die folgende Beschreibung:

Detail formatter error: An exception occurred: java.lang.StackOverflowError

Mein Code:

public class User { 
    private Set<GrantedRole> roles = new HashSet<GrantedRole>(); 

    public User() { 
     super(); 
    } 
    public User(String name, String password) { 
     this.name = name; 
     this.password = password; 
    } 

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "user") 
    public Set<GrantedRole> getRoles() { 
     return roles; 
    } 

    public void setRoles(Set<GrantedRole> roles) { 
     this.roles = roles; 
    } 

    // equals and hashCode are based on username 
    // toString is based on all fields 
} 

public class GrantedRole { 
    private user user; 

    public GrantedRole() { 
     super(); 
    } 
    public GrantedRole(User user, Role role, Organization organization) { 
     this.user = user; 
     this.role = role; 
     this.organization = organization; 
    } 

    @ManyToOne 
    @NotNull 
    public User getUser() { 
     return user; 
    } 

    public void setUser(User user) { 
     this.user = user; 
    } 

    // equals and hashCode are based on all fields 
    // toString was based on all fields, I've changed it to not include User. 
} 

public class Test { 
    public void testStuff() { 
     User user = new User("name"); 
     GrantedRole role = new GrantedRole(user, "role"); //this sets the user field 
     user.getRoles().add(role); //doesn't throw Exception, but debugging shows InvocationTargetException and StackOverflowException 
     System.out.println(user.getRoles()); //throws StackOverflowException, as I would expect 
    } 
} 

Es war mein Verständnis, dass ich in der Lage sollte eine bidirektionale einzurichten Beziehung auf diese Weise. Ich lese mehrere Tutorials, like this one, und ich sehe nicht, was ich anders mache, um die ADD (Rolle) falsch zu machen.

Ich habe einige Trivial-Code weggelassen, wenn es benötigt wird, werde ich es gerne zur Verfügung stellen. Ich habe keinen Code erstellt, um sicherzustellen, dass eine GrantedRole mit einem Verweis auf einen Benutzer von diesem Benutzer referenziert wird, aber ich denke, dass dies für das Problem, das ich habe, nicht relevant ist.

+0

1. Sind die Getter/Setter wirklich trivial? 2. Der vollständige Stapel des 'StackOverflowError' würde viel helfen zu verstehen, was passiert. –

+0

Und Sie können den Code der beiden Konstruktoren 'User (String)' und 'GrantedRole (User, String)' hinzufügen, so dass wir verstehen, was Sie gerade tun. – eternay

+2

Es könnte die 'toString()' Methode rekursiver Aufruf sein. Sie sollten sicherstellen, dass Sie die Methoden wie 'equals',' hashCode', ... nicht vom Kind im Elternteil aufrufen, nur Kinder sollten am Aufruf von Eltern interessiert sein. –

Antwort

15

Also, ich war nur dumm und hatte einen rekursiven Aufruf in den toString() -Methoden. User.toString() hat versucht, die Rollen zu drucken, und GrantedRole.toString() hat versucht, den Benutzer zu drucken.

Ich reparierte es, indem ich die GrantedRole.toString() änderte, um user.getUsername() zu drucken und so den Zyklus zu brechen.

+2

das gleiche kann mit Ihrer .hashCode() -Methode passieren :) –

+0

danke, nette Antwort – FAndrew

+1

Danke, stecken Sie mit diesem stackoverflow Problem für mehr als einen Tag für eins zu eins bidirektional.Lösen Sie das Problem durch Ändern der tostring() –