【问题标题】:StackOverflowError: null when doing a get requestStackOverflowError:执行获取请求时为空
【发布时间】:2018-07-07 16:15:01
【问题描述】:

当我尝试向我的 /users 端点发出 get 请求时遇到问题,而不是返回我想要的,而是在下面返回此错误:

2018-07-07 17:00:06.636 ERROR 294108 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"]->org.hibernate.collection.internal.PersistentSet[0]->io.union.restapi.domain.User["group"]->io.union.restapi.domain.Group["users"])] with root cause

java.lang.StackOverflowError: null
	at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_171]
	at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~

我的端点方法:

 @Override
    public ResponseEntity<List<M>> findAll() {
        List<M> models = repository.findAll();

        if(models == null || models.isEmpty()){
            return ResponseEntity.noContent().build();
        }

        return ResponseEntity.ok(models);
    }

用户模型:

@Entity
@Table(name = "UN_USERS")
public class User extends AbstractModel {

    @Column(name = "USERNAME", unique = true)
    private String username;

    @Column(name = "UUID")
    private String uuid;

    @Column(name = "COINS")
    private long coins;

    @Column(name = "TOKENS")
    private long tokens;

    @ManyToOne
    @JoinColumn(name = "GROUP_ID", nullable = true)
    private Group group;

    //getters & setters... 
}

组模型:

@Entity
@Table(name="UN_GROUPS")
public class Group extends AbstractModel{

    private String prefix;

    @OneToMany(mappedBy = "group")
    private Set<User> users;

    @ManyToMany(mappedBy = "groups")
    private Set<Permission> permissions;
}

什么可能导致此错误,我该如何解决?

【问题讨论】:

  • nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) 我不是 Spring 方面的专家,但我认为您应该寻找自我引用或导致递归的原因。

标签: java spring hibernate spring-boot stack-overflow


【解决方案1】:

通过分析报错信息,这部分具体:

through reference chain: io.union.restapi.domain.Group["users"]-&gt;org.hibernate.collection.internal.PersistentSet[0]-&gt;io.union.restapi.domain.User["group"]-&gt;io.union.restapi.domain.Group["users"]

我们得到参考链形成了一个循环。您遇到了杰克逊无限递归问题,有几种方法可以解决它。你可以找到一篇很好的文章来介绍处理它的方法here

【讨论】:

    【解决方案2】:

    您必须将@JsonIgnore 添加到private Group group; 以便杰克逊可以忽略它。否则,jackson 将尝试序列化group,然后它将创建一个循环,从Set&lt;User&gt; users 对象中的Set&lt;User&gt; users 回到User 中的group 属性。

    【讨论】:

    • 我无法添加 @JsonIgnore,它会从 json 响应中删除该属性。嗯,但可以创建一个 DTO 来解决这个问题
    • 是的,创建一个很好的 dto。无论如何我必须隐藏领域模型。
    【解决方案3】:

    你可以使用@OneToMany(mappedBy =

    @OneToMany(mappedBy = "group",cascade = CascadeType.ALL ,fetch = FetchType.LAZY)
    

    【讨论】:

    • 嗨@ram,欢迎来到 StackOverflow!在这里回答问题时,除了代码行之外,尽量对代码的含义做一点解释。此外,您可以通过在其周围放置 ` 来格式化代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 2012-09-29
    • 1970-01-01
    相关资源
    最近更新 更多