英文:
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 = "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() {
}
}
Book:
@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"])]
Full code is available here:
答案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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论