首页 > 解决方案 > Jackson - 反序列化 ManyToOne 关系时出现延迟列表初始化错误

问题描述

我有 2 个简单的课程:

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 有关吗?

这是因为我不使用自定义序列化器/反序列化器吗?

标签: javajackson

解决方案


如果您使用 JPA,您的所有实体都将通过字节码进行增强,以允许延迟加载等。它们并不真正适合序列化,除非是知道它的hibernate。但是杰克逊不知道,所以它会搞砸增强的字节码。

对 JPA 映射和 Jackson 映射使用相同的类也不是一个好主意。JPA 类具有映射到列等的字段,而 Jackson 的类映射到 javascript 模式。如果你在同一个类中使用它们,你永远不能改变你的数据库模式而不影响你的 JSON 模式,并且可能破坏与使用 JSON 的人的向后兼容性。

最好有单独的类(DTO)供 Jackson 使用,并在它们之间做一些映射。或者使用mapstruct自动生成映射器。


推荐阅读