【问题标题】:Spring boot JSON return infinite nested objectsSpring Boot JSON 返回无限嵌套对象
【发布时间】:2020-03-02 16:03:44
【问题描述】:

我的代码中有以下内容:

公司实体

@Entity
@Table(name = "company")
public class Company{
   @OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
   @JsonUnwrapped
   private Set<User> users;
}

用户实体

@Entity
@Table(name="user")
public class User{
    @ManyToOne(cascade = CascadeType.REFRESH)
    @JoinColumn(name="company_id")
    private Company company;
}

公司控制器

@GetMapping("/company")
public ResponseEntity<Object> getAllCompanies(){
    List<Company> allCompanies = companyService.findAll();
    return ResponseEntity.ok(allCompanies);

}

问题是当我在浏览器中调用/company 时,我得到了包括公司对象在内的users 对象。像这样的

[
    {
        "id": 1,
        "name": "company",
        "users": [
            {
                "id": 14,
                "firstName": "Yamen",
                "lastName": "Nassif",
                "company": {
                    "id": 1,
                    "name": "company",
                    "users": [
                        {
                            "id": 14,
                            "firstName": "Yamen",
                            "lastName": "Nassif",
                            "company": {
                                "id": 1,
                                "name": "company",
                                "users": [

...

当我 getAllUsers 公司和用户也在扩展时也是如此。

我的数据库看起来还不错。

它无穷无尽,当然 Stackoverflow 错误在控制台中。我该如何解决这个问题?

【问题讨论】:

    标签: spring-boot spring-data-jpa


    【解决方案1】:

    你有这个错误是因为无限递归。

    CompanyUser 上有一个链接,UserCompany 上有一个链接。

    您至少有两个选择:

    例如

    @GetMapping("/company")
    public ResponseEntity<Object> getAllCompanies() {
        List<Company> allCompanies = companyService.findAll();
        List<CompanyDto> allCompanyDtoList = convertToCompanyDtoList(allCompanies);
        return ResponseEntity.ok(allCompanyDtoList );
    }
    

    就我个人而言,我更喜欢第二种选择,因为返回实体不是一个好习惯。

    【讨论】:

    • 我尝试了一些不同的方法:从公司中删除 @OneToMany(mappedBy = "company", cascade = CascadeType.ALL) 不起作用,然后我遇到了持久性错误
    • 我的意思是从 Company 中删除整个 users 对象,但有些东西坏了。
    • 我不确定,但 allCompanies 不会已经中断或者即使没有 JSON 化也已经扩展?
    • 不,使用您在问题中提供的代码获取allCompanies 不会破坏任何内容。此错误与将实体序列化为您从休息控制器返回的 JSON 时的无限循环有关。
    • 好的,谢谢,我会试试的。但是如何从一个实体中删除其中一个链接呢?以公司用户为例 ?我怎样才能做到这一点而不会出错?
    【解决方案2】:

    您可以使用@JsonIgnore 注解来防止此类行为。这通常发生在实体内的双向映射中。它是由无限递归引起的。

    @Entity
    @Table(name="user")
    public class User{
        @ManyToOne(cascade = CascadeType.REFRESH)
        @JoinColumn(name="company_id")
        @JsonIgnore
        private Company company;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 2015-05-31
      • 2019-07-12
      • 2018-05-17
      • 2021-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多