javahibernatejsonbimmutables-libraryhibernate-types

Deserialization exception with Immutables and Hibernate vladmihalcea jsonb type


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?


Solution

  • 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.