36

Hibernate 5 does not support the PostgreSQL jsonb data type by default.

Is there any way to implement jsonb support for Hibernate + Spring JPA?

If there is a way, what are the pros and cons of using jsonb with Hibernate?

1

3 Answers 3

49

Thanks Vlad Mihalcea we have such opportunity! )

He created hibernate-types lib:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>2.1.1</version>
</dependency> 

which adds a support of 'json', 'jsonb' and other types to Hibernate:

@Data
@NoArgsConstructor
@Entity
@Table(name = "parents")
@TypeDefs({
        @TypeDef(name = "string-array", typeClass = StringArrayType.class),
        @TypeDef(name = "int-array", typeClass = IntArrayType.class),
        @TypeDef(name = "json", typeClass = JsonStringType.class),
        @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
})
public class Parent implements Serializable {

    @Id
    @GeneratedValue(strategy = SEQUENCE)
    private Integer id;

    @Column(length = 32, nullable = false)
    private String name;

    @Type(type = "jsonb")
    @Column(columnDefinition = "jsonb")
    private List<Child> children;

    @Type(type = "string-array")
    @Column(columnDefinition = "text[]")
    private String[] phones;

    public Parent(String name, List<Child> children, String... phones) {
        this.name = name;
        this.children = children;
        this.phones = phones;
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Child implements Serializable {
    private String name;
}

More info: 1, 2

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks @Cepr0 for the answer. Actually, does this library support search by an object field? As I can see this library is pretty raw and community not really big, is it reliable?
@Aventes Vlad is one of the Hibernate authors
@Aventes The Hibernate Types framework has over 750 GitHub stars and gets over 400k monthly downloads. So, the community is quite big because the Hibernate Types framework provides support for JSON, ARRAY, Inet, HStore, TSVector, DBs-specific Enums, YearMonth, and many other features.
@VladMihalcea Why do the Hibernate not support these types? Because they are not standard sql type?
JSON and ARRAY are standard, but thry are not supported by all DBs that Hibernate supports. One day, it might support the. In the meantime, you csn use the Hibernate Types project.
|
16

Update for Hibernate 6+ (2022+)

With the advent of Hibernate 6, mapping to PostgreSQL JSON(B) has became possible out-of-the box.

One only needs to annotate the field with JdbcTypeCode(SqlTypes.JSON).

With non-typed JSON:

@Entity
public class Entity {
    ...
    @JdbcTypeCode(SqlTypes.JSON)
    private Map<String, String> payload;
    ...
}

(Although not every JSON will serialize into a Map).

With JSON which is serialized as a custom Java type:

public class Foo implements Serializable {
  
    private String strValue;
    private Long longValue;
  
    public String getStrValue() {
        return strValue;
    }
  
    public void setStringProp(String stringProp) {
        this.strValue = strValue;
    }
  
    public Long getLongValue() {
        return longProp;
    }
  
    public void setLongValue(Long longValue) {
        this.longValue = longValue;
    }
}


@Entity
public class Entity {
    ...
    @JdbcTypeCode(SqlTypes.JSON)
    private Foo fooJson;
    ...
}

Please see this article for more examples: https://thorben-janssen.com/persist-postgresqls-jsonb-data-type-hibernate/

5 Comments

Does not work. Despite @JdbcTypeCode(SqlTypes.JSON) on the entity field I am getting FIELD is of type jsonb but expression is of type bytea. Neither did @Type(JsonBinaryType.class) @Column(columnDefinition = "jsonb") help. Hibernate is just a massive pain.
What adds insult to the injury is Hibernate team's response to community complaints: stackoverflow.com/a/70294493/4125622
@Phil I guess that it is probably not related to @JdbcTypeCode(SqlTypes.JSON) specifically. What is the sql column type and how do you fetch the data? HQL, native query, spring data jpa?
@Phil try making the definition : @JdbcTypeCode(SqlTypes.JSON) @Column(columnDefinition = "jsonb") private Map<String, String> payload;
In case of using Hibernate 6 you might need to add jackson-databind dependency: xml <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.18.2</version> </dependency>
6

@Cepr0-s answer is correct but although I got some issues with it. I was getting exception when trying to use it with PostgreSQL org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111. Way to solve this, in my case, was adding custom hibernate dialect. This resource might be helpful.

// CustomPostgreSQLDialect.java
public class CustomPostgreSQLDialect extends PostgreSQL10Dialect {

    public CustomPostgreSQLDialect() {
        super();
        registerHibernateType(Types.OTHER, StringArrayType.class.getName());
        registerHibernateType(Types.OTHER, IntArrayType.class.getName());
        registerHibernateType(Types.OTHER, JsonStringType.class.getName());
        registerHibernateType(Types.OTHER, JsonBinaryType.class.getName());
        registerHibernateType(Types.OTHER, JsonNodeBinaryType.class.getName());
        registerHibernateType(Types.OTHER, JsonNodeStringType.class.getName());
    }
}

-

# application.yml
spring:
  jpa:
    properties:
      hibernate:
        dialect: "com.test.CustomPostgreSQLDialect"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.