不可变和 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
的问题,它应该可以工作。
我正在使用 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
的问题,它应该可以工作。