【问题标题】:Jackson: JsonBackReference - infinite recursion problemJackson:JsonBackReference - 无限递归问题
【发布时间】:2019-01-16 12:35:54
【问题描述】:

我对 JSON 的了解有限,希望您能指出正确的方向。

我正在尝试发布一个对象(库),但由于无限递归,这会引发异常

public class Library{
    private List<Book> books= new 
    ArrayList<Book>();
    //omitting rest of attributes, constructor, 
   and getter/setters
}

public class Book{
    private List<Author> authors= new 
    ArrayList<Author>();
    //omitting rest of attributes, constructor, 
    and getter/setters
}

public class Author{
    private Book book;
    //omitting rest of attributes, constructor, 
    and getter/setters
}

如您所见,这会导致无法序列化的无限递归:

Library -> Book -> Author -> Book -> Author...

这设计很糟糕,但我没有更改模型的选项。

我尝试使用JsonManagedReferenceJsonBackReference 来解决这个问题。

public class Library{
    @JsonManagedReference(value="book")
    private List<Book> books= new 
    ArrayList<Book>();
    //omitting rest of attributes, constructor, 
   and getter/setters
}

public class Author{
    @JsonBackReference(value="book")
    private Book book;
    //omitting rest of attributes, constructor, 
    and getter/setters
}

但是,这不起作用,我收到错误:

原因:java.lang.IllegalArgumentException:无法处理 托管/后向引用“书”:未找到后向引用属性 type [集合类型;类 java.util.List,包含 [简单类型, 类.......model.Book]]

如果我删除@JsonManagedReferenceannotation 并保留BackReference,我可以序列化对象。但是,序列化对象将Author 中的Book 实例设置为null,导致尝试将其持久化到数据库中时出现异常。

我是否将注释放置在正确的位置?有什么建议吗?

编辑:正如回复中所建议的,我的注释放置错误。以下工作用于序列化对象,但 Author 正在丢失对 Book 的引用

public class Book{
@JsonManagedReference
private List<Author> authors= new 
ArrayList<Author>();
}

public class Author{
@JsonBackReference
private Book book;
}

这解决了无限递归的问题。但是,我得到 SQL 异常,因为无法插入空值。

Library -> Book -> Author X Book

author 表包含对该书的不可为空的引用。

谢谢

【问题讨论】:

标签: java json spring serialization jackson


【解决方案1】:

您的注释好像放错地方了。

为什么在防止AuthorBook 之间的递归时,Library 具有用于书籍的ManagedReference

应该是这样的:

public class Author {
    @JsonBackReference
    private Book book;
}

public class Book {
    @JsonManagedReference
    private List<Author> authors = new ArrayList<Author>();
}

此外,Author 与一本书的一对一关系肯定是错误的模型。从逻辑上讲,Author 可能拥有许多 books

【讨论】:

  • 为了清楚起见,修改了类的名称,但是是的,我应该使用与 Book/Author 不同的示例。
  • 您的方法很有意义,我刚刚尝试过。不幸的是我得到了同样的错误。我将使用 value 参数再试一次。
  • 这些注释在反方向放置时起作用:作者中的 BackReference 和 Book 中的 ManagedReference。但是,尝试保存到数据库时出现 SQL 异常。问题是,在序列化之后,Book (in author) 被设置为 null。我会更新问题
  • @Fithos 太好了,我编辑了我的答案,因此它可以成为解决问题的正确指南。但不要在一个主题上发布许多不相关的问题。如果问题已解决 - 接受答案并发布新答案。这样做会增加您获得答案的机会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-12
  • 2021-12-10
  • 2011-03-20
相关资源
最近更新 更多