java - Jackson - 反序列化 ManyToOne 关系时出现延迟列表初始化错误
问题描述
我有 2 个简单的课程:
Cat
CatStore
Cat
没有什么特别的,并且CatStore
有一个List<Cat>
,关系映射为:
在Cat
课堂上:
@ManyToOne
private CatStore catstore;
在CatStore
:
@OneToMany(mappedBy="catstore", fetch=FetchType.EAGER)
private List<Cat> cats;
这种关系似乎工作正常,因为杰克逊可以在我运行时为我生成正确的 JSON
String json = mapper.writeValueAsString(catStore);
但是,如果我尝试反序列化我刚刚生成的 JSON,请使用以下行:
CatStore c2 = mapper.readValue(json, CatStore.class);
我得到一个JsonProcessingException
说法
failed to lazily initialize a collection, could not initialize proxy - no Session (through reference chain: fr.truc.java.cleanspringbootMVC.model.CatStore["cats"]
如果没有CatStore
类似以下 JSON 的猫,则反序列化实际上可以工作:
{
"id":123,
"cats":["org.hibernate.collection.internal.PersistentBag",[]],
"name":"NO cats"
}
但这会触发错误:
{
"id": 121,
"cats": ["org.hibernate.collection.internal.PersistentBag", [
["fr.truc.java.cleanspringbootMVC.model.Cat", {
"id": 118,
"name": "luc",
"nbPattes": 4
}],
["fr.truc.java.cleanspringbootMVC.model.Cat", {
"id": 119,
"name": "andré",
"nbPattes": 4
}],
["fr.truc.java.cleanspringbootMVC.model.Cat", {
"id": 120,
"name": "cheval",
"nbPattes": 4
}]
]],
"name": "Cat en kit"
}
我真的不知道为什么这里会触发延迟加载异常,因为数据包含在 JSON 字符串中。
这与 PersistentBag 有关吗?
这是因为我不使用自定义序列化器/反序列化器吗?
解决方案
如果您使用 JPA,您的所有实体都将通过字节码进行增强,以允许延迟加载等。它们并不真正适合序列化,除非是知道它的hibernate。但是杰克逊不知道,所以它会搞砸增强的字节码。
对 JPA 映射和 Jackson 映射使用相同的类也不是一个好主意。JPA 类具有映射到列等的字段,而 Jackson 的类映射到 javascript 模式。如果你在同一个类中使用它们,你永远不能改变你的数据库模式而不影响你的 JSON 模式,并且可能破坏与使用 JSON 的人的向后兼容性。
最好有单独的类(DTO)供 Jackson 使用,并在它们之间做一些映射。或者使用mapstruct自动生成映射器。
推荐阅读
- python - 有没有办法将文本文件导入 python 中的列表,并使每个字符在该列表中成为单独的项目?
- python-3.x - NameError:在封闭范围内分配之前引用了自由变量“列表”
- git - 如何在不安全的服务器上克隆私人 github 存储库(不暴露您的密码)?
- javascript - 仅当存在键时如何解构对象
- wordpress - WordPress上的重力形式
- wcf - 更改自签名证书会导致通信问题?
- bootstrap-4 - 将选项动态添加到 Bootstrap 可搜索选择
- database - 这个实体关系图正确吗?
- android - Robot Framework Appium 库:获取 ValueError:某些关键字不支持带有前缀“//* [@class”的元素定位器
- solr - 基于函数结果的 Solr faceting