我正在使用fasterxml,并且我有两个具有“一对多”或“多对一”关系的对象。例如,Author 类和 Book 类,一位作者有多本书,一本书有一位作者。我可以告诉fasterxml不要序列化这本书的作者,只有当这本书在它的作者的书籍集合中时,而是当这本书本身时,才序列化它。
作者类别:
public class Author{
public int id;
public string name;
@JsonManagedReference
public Set<Book> books;
}
预订课程:
public class Book{
public int id;
public string name;
@JsonBackReference
public Author author;
}
如果我只想获取作者,那么该设置就很好,因为书籍已就位,并且它们的作者属性没有被序列化,但如果我只想序列化这本书,它的作者又没有被序列化,因为“@JsonBackReference”注释。对于上述情况有没有解决办法?如果您不明白我的意思,这里还有一些例子......
当我序列化 Autor 时:
{
id:3,
name: "Ivan Vazov"
books:[
{
id:5,
name: "Under the Yoke"
}
]
}
这就是我想要的。
当我连载一本书时:
{
id:5,
name: "Under the Yoke"
}
但我不想要这个,我想要这个:
{
id:5,
name: "Under the Yoke",
author: {
id:3,
name: "Ivan Vazov"
}
}
关于此事的任何想法都很棒!谢谢。
如果您希望从两侧(书籍、作者)序列化引用,那么杰克逊将面临循环引用的问题,在序列化这两个对象之一时,它会陷入无限的引用循环中。
解决方法是使用
@JsonManagedReference
和 @JsonBackReference
,其中 jackson 忽略一侧并仅序列化另一侧以避免循环引用。
问题的解决方案(当您想要序列化双方时)是创建单独的 DTO 对象(AuthorDto、BookDto),而不是从控制器返回要序列化的 Author,而是返回 AuthorDto。与书相同。那么循环引用问题就不再存在了,双方都将有问题的引用序列化。
DTO 是解决更复杂场景的方法,尤其是在入站方面。为了动态过滤更简单的用例,我为 jackson 编写了一个插件来使用 antpath 样式过滤。也许对你有帮助:
在 Book 模式中写入 @JsonIgnoreProperties("books") // 忽略作者 lors de la sérialization 的冠军书籍
私人作者作者;
在作者模式中写入 @JsonIgnoreProperties("author") // 忽略序列化书籍中的冠军作者
私有集书籍= new HashSet<>();
您已在 ManyToOne 关系端添加获取类型,如下所示。
要获取所有书籍实体,请添加获取类型 Eager。
@多对一( fetch = FetchType.EAGER, 可选=假 )
要仅获取书籍实体,然后添加延迟获取。
@多对一( fetch = FetchType.LAZY, 可选=假 )