I'm using Immutables and Hibernate Types to serialize an object as jsonb
into PostgreSQL.
My entity is mapped like this:
@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;
}
The Aggregate
looks like this:
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXISTING_PROPERTY,
property = "aggregateType",
defaultImpl = GenericAggregate.class,
visible = true
)
@JsonSubTypes({
@Type(ConcreteAggregate.class)
})
public interface Aggregate {
}
And my concrete type for Aggregate
:
@Value.Immutable
@JsonTypeName("concrete-aggregate")
@JsonSerialize(as = ImmutableConcreteAggregate.class)
@JsonDeserialize(as = ImmutableConcreteAggregate.class)
public interface ConcreteAggregate extends Aggregate {
// fields
}
I get the following exception when reading from the database:
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$2.deepCopyNotNull(JsonTypeDescriptor.java:39)
How can I solve this?
TL;DR
Make your JSON DTO (the interface Aggregate
in this case) implement java.io.Serializable
.
Why?
This exception happens because the Hibernate Types tries to clone the object in com.vladmihalcea.hibernate.type.util.ObjectMapperJsonSerializer
using Jackson through ObjectMapper
if your class does not implement java.io.Serializable
. So it's simply a matter of making your JSON DTO implement java.io.Serializable
and it should work.