【问题标题】:How to serialize and deserialize a Set attribute with Jackson and Hibernate如何使用 Jackson 和 Hibernate 序列化和反序列化 Set 属性
【发布时间】:2026-02-23 19:35:01
【问题描述】:

我有两个使用 Hibernate 持久化的简单 POJO 模型,我正在使用 Jackson 将对象序列化和反序列化为 JSON。

这是我的模型 TestCar 和 TestPart:

public class TestCar
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id; 

    private String name;

    @OneToMany(targetEntity = TestPart.class, mappedBy = "car", cascade = { CascadeType.PERSIST }, orphanRemoval=true, fetch = FetchType.LAZY)
    private Set<TestPart> parts = new HashSet<>();
}

public class TestPart
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id; 

    private String name;

    @JsonIgnore
    @ManyToOne
    private TestCar car;
}

我的杰克逊初始化:

Hibernate4Module h4m = new Hibernate4Module();
h4m.enable(Hibernate4Module.Feature.FORCE_LAZY_LOADING);

mapper = new ObjectMapper();
mapper.registerModule(h4m);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
mapper.enableDefaultTyping();

private Set&lt;TestPart&gt; pars 存在问题,因为它被序列化为org.hibernate.collection.internal.PersistentSet

{
    "id" : 1,
    "name" : "Fiat",
    "parts" : [ "org.hibernate.collection.internal.PersistentSet", [ [ "com.acme.TestPart", {
            "id" : 1,
            "name" : "puerta"
      } ]
     ] ]
}

当我尝试反序列化它时会抛出一个错误:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
at org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:155)
at org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:160)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:308)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:259)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:116)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromArray(AsArrayTypeDeserializer.java:53)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserializeWithType(CollectionDeserializer.java:320)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:497)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:101)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:276)

有没有办法将休眠的 PersistentSet 序列化为一个简单的 Set ?

【问题讨论】:

    标签: java json hibernate serialization


    【解决方案1】:

    您似乎没有使用安装了模块的 ObjectMapper。也许您应该重新分配映射器变量?不确定 ObjectMapper 在多大程度上是可变的或构建器。

    【讨论】:

    • 嗨一月。我尝试重新评估 regirsterModule 的返回值,但没有任何改变。有什么想法吗?
    • JSON 输出不应该和你的一样。 JSON 应该看起来像一个常规集合或列表(JSON 中的一个数组)。您不应该看到任何与“持久集”相关的内容。您的 JSON 现在在未启用插件的情况下被序列化(我知道扩展程序的行为方式)并且您正在尝试反序列化垃圾 JSON。
    • 好的,这很好。所以问题在于序列化过程。我猜 Hibernate4Module 已加载,因为 FORCE_LAZY_LOADING 功能正在工作。另一方面,我实例化了 Hibernet4Module,因为它记录在 github 上的项目页面上。我发现的所有示例都使用与我相同的代码。
    • 嗨 Jan,当您使用具有 Set 或 List 属性 + Hibernate4Module + enableDefaultTyping() 的实体时,可能会出现问题。如果我禁用默认类型设置,则该示例有效,因为类名未序列化,但我确实需要它,因为我正在序列化多态对象。