9

我有实体 User 和 GrantedRole 具有双向一对多关系。

当我尝试将 GrantedRole 添加到 User 中的 Set 时,没有抛出异常,但是当我调试 User 和 GrantedRole 对象的变量时,其描述为

com.sun.jdi.InvocationException 发生调用方法。

调试时可以读取变量的不同字段,但是当我选择 User 中的角色字段或 GrantedRole 中的用户字段时,我会得到与上面相同的描述。当我进入用户中的授予角色集时,我最终找到了以下描述:

详细格式化程序错误:发生异常: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
    }
}

我的理解是,我应该能够以这种方式建立双向关系。我阅读了多个教程,比如这个,我看不出我在做什么不同的事情来导致 .add(role) 出错。

我遗漏了一些琐碎的代码,如果需要,我很乐意提供。我没有编写代码来确保引用用户的 GrantedRole 作为回报被该用户引用,但我认为这与我遇到的问题无关。

4

1 回答 1

19

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

我通过将 GrantedRole.toString() 更改为打印 user.getUsername() 来修复它,从而打破了循环。

于 2013-06-20T08:29:33.510 回答