vladmihalcea/hypersistence-utils

JsonBinaryType is not working for nativeQuery insert

seanalbert opened this issue · 1 comments

Describe the bug
Since I updated to Spring Boot 3 and Hibernate 6, native query inserts that use the JsonBinaryType do not work.

It worked in Hibernate 5 with the following

@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
@Entity
@Table(name = "event")
public class Event {
    @Type(type = "jsonb")
    @Column(columnDefinition = "jsonb")
    private List<Location> locations;
    .....
}
entityManager.createNativeQuery("INSERT INTO event (id, locations) VALUES (:id, :locations)")
        .setParameter("id", event.getId())
        .setParameter("locations", new TypedParameterValue(JsonBinaryType.INSTANCE, event.getLocations()))
        .executeUpdate();

In Hibernate 6 I have the following

@Entity
@Table(name = "event")
public class Event {
    @Type(JsonBinaryType.class)
    @Column(columnDefinition = "jsonb")
    private List<Location> locations;
    .....
}
entityManager.createNativeQuery("INSERT INTO event (id, locations) VALUES (:id, :locations)")
        .setParameter("id", event.getId())
        .setParameter("locations", new TypedParameterValue<>(JsonBinaryType.INSTANCE, event.getLocations()))
        .executeUpdate();

I had to make Location class Serializable to get passed a class not serializable exception and now I am hitting the error

org.postgresql.util.PSQLException: ERROR: column "locations" is of type jsonb but expression is of type bytea
  Hint: You will need to rewrite or cast the expression.

To Reproduce

I have created a replicating test case with some different thing I have tried to get around the issue. master...seanalbert:hypersistence-utils:postgres-jsonb-native-insert

Expected behavior
data should be written to postgres in the correct format without any errors

figured it out. fix was to pass List.class to the JsonBinaryType constructor

entityManager.createNativeQuery("INSERT INTO event (id, locations) VALUES (:id, :locations)")
        .setParameter("id", event.getId())
        .setParameter("locations", new TypedParameterValue<>(new JsonBinaryType(List.class), event.getLocations()))
        .executeUpdate();