不可变和 Hibernate vladmihalcea jsonb 类型的反序列化异常

Deserialization exception with Immutables and Hibernate vladmihalcea jsonb type

我正在使用 Immutables and Hibernate Types 将对象序列化为 jsonb 到 PostgreSQL。

我的实体是这样映射的:

@Entity
@Table(schema = "data", name = "event")
@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
public class Event {

    @Id
    @Column(name = "id")
    private String id;

    @Type(type = "jsonb")
    @Column(name = "payload")
    private Aggregate payload;

}

Aggregate 看起来像这样:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.EXISTING_PROPERTY,
        property = "aggregateType",
        defaultImpl = GenericAggregate.class,
        visible = true
)
@JsonSubTypes({
        @Type(ConcreteAggregate.class)
})
public interface Aggregate {
}

我的具体类型 Aggregate:

@Value.Immutable
@JsonTypeName("concrete-aggregate")
@JsonSerialize(as = ImmutableConcreteAggregate.class)
@JsonDeserialize(as = ImmutableConcreteAggregate.class)
public interface ConcreteAggregate extends Aggregate {
    // fields
}

从数据库读取时出现以下异常:

java.lang.IllegalArgumentException: Class com.example.ConcreteAggregate not subtype of [simple type, class com.example.ConcreteAggregateBuilder$ImmutableConcreteAggregate]

    at com.fasterxml.jackson.databind.type.TypeFactory.constructSpecializedType(TypeFactory.java:357)
    at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._findDeserializer(TypeDeserializerBase.java:191)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:113)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:97)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1178)
    at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:68)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
    at com.vladmihalcea.hibernate.type.util.ObjectMapperWrapper.fromString(ObjectMapperWrapper.java:42)
    at com.vladmihalcea.hibernate.type.util.ObjectMapperJsonSerializer.clone(ObjectMapperJsonSerializer.java:22)
    at com.vladmihalcea.hibernate.type.util.ObjectMapperWrapper.clone(ObjectMapperWrapper.java:73)
    at com.vladmihalcea.hibernate.type.json.internal.JsonTypeDescriptor.deepCopyNotNull(JsonTypeDescriptor.java:39)

我该如何解决这个问题?

TL;DR

使您的 JSON DTO(在本例中为接口 Aggregate)实现 java.io.Serializable.

为什么?

发生此异常是因为如果您的 class 未实现 java.io.Serializable,则 Hibernate 类型会尝试通过 ObjectMapper 使用 Jackson 克隆 com.vladmihalcea.hibernate.type.util.ObjectMapperJsonSerializer 中的对象。所以这只是让你的 JSON DTO 实现 java.io.Serializable 的问题,它应该可以工作。