2013-06-19 46 views
7

我有实体用户和GrantedRole有双向一对多关系。JPA/Hibernate双向多对一结果StackOverflowException

当我尝试将GrantedRole添加到该集合的用户,没有抛出异常,但是当我调试变量用户和GrantedRole对象有一个说明,上面写着

com.sun.jdi.InvocationException occurred invoking method.

不同领域因为变量可以在调试时读取,但是当我在User中选择角色字段或在GrantedRole中的用户字段中时,我会得到与上面相同的说明。 当我进入设置GrantedRole的用户,我最终找到了如下描述:

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

我的代码:

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 
    } 
} 

这是我的理解是,我应该能够建立一个双向这种关系。我阅读了多个教程,like this one,我不明白我在做什么不同的事情导致.add(角色)出错。

我遗漏了一些简单的代码,如果需要的话,我会很乐意提供它。我没有制作代码来确保用户引用的GrantedRole被用户引用,但我认为这与我遇到的问题无关。

+0

1.获取者/设置者真的很微不足道? 2. StackOverflowError的完整堆栈将有助于理解正在发生的事情。 –

+0

你可以添加两个构造函数'User(String)'和'GrantedRole(User,String)'的代码,这样我们就可以明白你在做什么了。 – eternay

+2

它可能是'toString()'方法的递归调用。你应该确保你不要调用类似'equals','hashCode',...这样的方法来从父级中的孩子,只有孩子应该有兴趣从父级调用。 –

回答

15

所以,我只是很愚蠢,并在toString()方法中进行了递归调用。 User.toString()试图打印角色,而GrantedRole.toString()试图打印用户。

我修改了GrantedRole.toString()来打印user.getUsername(),从而打破了这个循环。

+2

您的.hashCode()方法可能会发生同样的问题:) –

+0

谢谢,很好的答案 – FAndrew

+1

谢谢,坚持这个一对一的双向超过一天的stackoverflow问题。解决了修改tostring() –