为什么RESTcontroller在JSON中多次返回相同的结果?

时间:2019-07-08 14:14:17

标签: java spring hibernate jpa

我的rest控制器无限期地为对象USER返回相同的对象。其他不需要USER对象的对象也可以正常工作。怎么了? 如果我删除一些吸气剂/吸气剂,就可以了,但是我实际上需要这里的一切... Spring引发异常-StackOverFlow exc和Java.lang.IllegalStateException:提交响应后无法调用sendError()

编辑:我发现问题出在“ getRoles()”-不幸的是,这对我来说非常重要,我需要将其包含在JSON中……如何使其起作用?

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "first_name")
    private String firstName;
    private String surname;
    private String email;
    private String password;

    @ManyToMany
    @JoinTable(
            name = "users_roles",
            joinColumns = @JoinColumn(
                    name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(
                    name = "role_id", referencedColumnName = "id"))
    private List<Role> roles;

    @JsonIgnore
    @ManyToMany
    @JoinTable(
            name="users_documents",
            joinColumns = @JoinColumn(
                    name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(
                    name="document_id", referencedColumnName = "id"))
    private List<Document> usersDocuments;


    @OneToMany(mappedBy="user")
    private List<Document> sharedDocuments;


    public User() {

    }

    public User(String firstName, String surname, String email, String password) {
        this.firstName = firstName;
        this.surname = surname;
        this.email = email;
        this.password = password;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public String getEmail() {
        return email;
    }

    public String getPassword() {
        return password;
    }


    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return getId() == user.getId();
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    }

    @Override
    public String toString() {
        return "User{" +
                "firstName='" + firstName + '\'' +
                ", surname='" + surname + '\'' +
                ", email='" + email + '\'' +
                ", roles=" + roles +
                '}';
    }
}

1 个答案:

答案 0 :(得分:0)

不确定是否可以专门处理您的数据,但是我能够通过使用Set而不是列表来解决我遇到的映射集合,从而解决了这个问题。

我注意到这个问题引起了杰克逊的很多指责。尽管就我而言,我注意到将FetchType设置为Lazy可以解决此问题,而无需修改Collection类型。

我猜想这将无济于事,因为无论如何您都需要实例化所有这些字段,而在这种情况下,延迟加载将很浪费。

尽管如此,您可能希望查看代码中实例化与其他实体相关联的对象的所有位置,并检查是否在意外情况下急切地实例化了其他对象。

您的equals()方法似乎完美地遵循了最佳实践。但是,我实际上不确定是否在此处创建User对象,在这种情况下,作为副作用,User的关联对象将急于实例化。

对此我可能会犯错(抱歉,暂时无法检查),但是如果您被卡住并且既不能利用延迟加载,也不能选择“列表中的集合”,则可能要留意类似的情况有问题的情况。