我有2个简单的课程:
Cat
CatStore
Cat
没有什么特别的,CatStore
有一个List<Cat>
,该关系映射为:
在Cat
类中:
@ManyToOne
private CatStore catstore;
在CatStore
中:
@OneToMany(mappedBy="catstore", fetch=FetchType.EAGER)
private List<Cat> cats;
该关系似乎工作正常,因为当我运行时Jackson可以为我生成正确的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有关吗?
这是因为我没有使用自定义的序列化器/反序列化器吗?
答案 0 :(得分:1)
如果使用JPA,则将通过字节码增强所有实体,以允许延迟加载等。它们实际上不适合序列化,除非休眠的人知道这一点。但是Jackson对此一无所知,因此它将破坏增强的字节码。
对JPA映射和Jackson映射使用相同的类也不是一个好主意。 JPA类的字段映射到列等,而Jackson的类映射到javascript模式。如果您在同一类中使用它们,则永远不能在不影响JSON模式的情况下更改数据库模式,并且可能破坏与使用JSON的人的向后兼容性。
最好为Jackson使用单独的类(DTO),并在它们之间进行一些映射。或使用mapstruct自动生成一个映射器。
答案 1 :(得分:0)
该错误似乎与mapper.enableDefaultTyping();
启用后,将在JSON中输出每个类的类型。 (我想要的)
由于某种原因,它会导致@ManyToOne出现上述错误
禁用后,PersistentBag不再出现在我的序列化JSON中,并且反序列化有效...