无法获取 JSON:无限递归

huangapple go评论76阅读模式
英文:

Could not GET json : Infinite recursion

问题

我在尝试向发布者存储库执行GET操作时遇到无限循环。

发布者:

@Data
@AllArgsConstructor
@Entity
@Table(name = "publisher")
public class Publisher {

    @Id
    private Long publisherID;

    private String name;
    private String location;

    public Publisher(@JsonProperty("publisherID") Long publisherID,
                     @JsonProperty("name") String name,
                     @JsonProperty("location") String location) {
        this.publisherID = publisherID;
        this.name = name;
        this.location = location;
    }

    @JsonManagedReference(value="Book-Publisher")
    @OneToMany(mappedBy = "publisher", cascade = CascadeType.ALL)
    private Set<Book> books;

    public Publisher() {
    }
}

图书:

@Data
@AllArgsConstructor
@Entity
@Table(name = "book")
public class Book {

    @Id
    private Long id;

    private String name;

    @JsonBackReference(value="Book-Publisher")
    @ManyToOne
    @JoinColumn(name="publisherID")
    private Publisher publisher;

    private int publicationYear;
    private int amount;

    @JsonManagedReference(value="BookAuthors-Book")
    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL)
    private Set<BookAuthors> bookAuthors;

    @JsonManagedReference(value="BookGenres-Book")
    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL)
    private Set<BookGenres> bookGenres;

    public Book(@JsonProperty("id") Long id,
                @JsonProperty("name") String name,
                @JsonProperty("publisherID") Long publisherID,
                @JsonProperty("publicationYear") int publicationYear,
                @JsonProperty("amount") int amount) {
        this.id = id;
        this.name = name;
        this.publicationYear = publicationYear;
        this.amount = amount;
        PublisherService publisherService = BeanUntil.getBean(PublisherService.class);
        this.publisher = publisherService.findByID(publisherID).get();
    }

    @JsonManagedReference(value="RentedBook-Book")
    @OneToMany(mappedBy = "book", cascade = CascadeType.ALL)
    private Set<RentedBook> rentedBooks;

    public Book() {
    }
}

警告信息如下:

2020-04-10 16:43:02.483  WARN 672 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [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: java.util.ArrayList[0]->com.vanyasav.domain.Publisher["books"])]

完整代码可以在此处找到:

https://github.com/vanyasav/Library

英文:

I am getting and infinite loop while trying to perform GET to a publisher repository.

Publisher:

@Data
@AllArgsConstructor
@Entity
@Table(name = &quot;publisher&quot;)
public class Publisher {
@Id
private Long publisherID;
private String name;
private String location;
public Publisher(@JsonProperty(&quot;publisherID&quot;) Long publisherID,
@JsonProperty(&quot;name&quot;) String name,
@JsonProperty(&quot;location&quot;) String location) {
this.publisherID = publisherID;
this.name = name;
this.location = location;
}
@JsonManagedReference(value=&quot;Book-Publisher&quot;)
@OneToMany(mappedBy = &quot;publisher&quot;, cascade = CascadeType.ALL)
private Set&lt;Book&gt; books;
public Publisher() {
}
}

Book:

@Data
@AllArgsConstructor
@Entity
@Table(name = &quot;book&quot;)
public class Book {
@Id

private Long id;

private String name;
@JsonBackReference(value=&quot;Book-Publisher&quot;)
@ManyToOne
@JoinColumn(name=&quot;publisherID&quot;)
private Publisher publisher;
private int publicationYear;
private int amount;
@JsonManagedReference(value=&quot;BookAuthors-Book&quot;)
@OneToMany(mappedBy = &quot;book&quot;, cascade = CascadeType.ALL)
private Set&lt;BookAuthors&gt; bookAuthors;
@JsonManagedReference(value=&quot;BookGenres-Book&quot;)
@OneToMany(mappedBy = &quot;book&quot;, cascade = CascadeType.ALL)
private Set&lt;BookGenres&gt; bookGenres;
public Book(@JsonProperty(&quot;id&quot;) Long id,
@JsonProperty(&quot;name&quot;) String name,
@JsonProperty(&quot;publisherID&quot;) Long publisherID,
@JsonProperty(&quot;publicationYear&quot;) int publicationYear,
@JsonProperty(&quot;amount&quot;) int amount) {
this.id = id;
this.name = name;
this.publicationYear = publicationYear;
this.amount = amount;
PublisherService publisherService = BeanUntil.getBean(PublisherService.class);
this.publisher = publisherService.findByID(publisherID).get();
}
@JsonManagedReference(value=&quot;RentedBook-Book&quot;)
@OneToMany(mappedBy = &quot;book&quot;, cascade = CascadeType.ALL)
private Set&lt;RentedBook&gt; rentedBooks;
public Book() {
}

}
> 2020-04-10 16:43:02.483 WARN 672 --- [nio-8080-exec-6] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [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: java.util.ArrayList[0]->com.vanyasav.domain.Publisher["books"])]

Full code is available here:

https://github.com/vanyasav/Library

答案1

得分: 0

当将 Publisher 的列表序列化为响应时,会调用 Publisher 字段的所有 getter 方法。因此,Publisher 关联字段 books 的 getter 也会被调用以设置值。这种情况会递归地发生,造成无限递归。

最好不要将实体用作响应。为出版商创建一个 DTO 类,然后将出版商实体的值映射到 DTO 中,然后发送响应。

要动态地将一个模型映射到另一个模型,可以使用 ModelMapper

英文:

When list of Publisher serialized for response, all getter method of Publisher field are called. So, Publisher relational field books's getter are also called to setvalue. This happened recursivly.That's cause of infinite recursion.

Its better to not use Entity as response. Create a DTO class for publisher then map publisher entity value into DTO then send response.

For dynamically map one model to another you can use ModleMapper

huangapple
  • 本文由 发表于 2020年4月10日 22:20:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/61142262.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定