How can I store a JSON String into PostgreSQL if the column type is JSONB using JPA?

2.7k Views Asked by At

Didn't Hibernate support this situation?

I have got a way to do that, it is: Use JSONB in JPA

But I cannot judge if it is safe. And I do know I and write the same code by myself, but didn't the official provide some easy way to do that like just add an annotation like @Type(type="jsonb").

1

There are 1 best solutions below

0
On BEST ANSWER

This is a very common requirement, so I wrote a very detailed article on this topic.

Hypersistence Utils project

The first thing you need to do is add the hypersistence-utils open-source project to your Maven or Gradle configuration file.

Entity mapping

Afterward, use the JsonType like this:

@Entity(name = "Book")
@Table(name = "book")
@TypeDef(
    name = "jsonb",
    typeClass = JsonType.class
)
public static class Book {
 
    @Id
    @GeneratedValue
    private Long id;
 
    @NaturalId
    private String isbn;
 
    @Type(type = "jsonb")
    @Column(columnDefinition = "jsonb")
    private String properties;
 
    //Getters and setters omitted for brevity
}

Persisting the entity

Now, when you persist the following Book entity:

entityManager.persist(
    new Book()
        .setIsbn("978-9730228236")
        .setProperties(
            "{" +
            "   \"title\": \"High-Performance Java Persistence\"," +
            "   \"author\": \"Vlad Mihalcea\"," +
            "   \"publisher\": \"Amazon\"," +
            "   \"price\": 44.99" +
            "}"
        )
);

Hibernate will persist the JSON attribute properly:

INSERT INTO book (
    isbn,
    properties,
    id
)
VALUES (
    '978-9730228236',
    '{"title":"High-Performance Java Persistence","author":"Vlad Mihalcea","publisher":"Amazon","price":44.99}',
    1
)

Fetching the entity

Fetching the entity works as expected:

Book book = entityManager
    .unwrap(Session.class)
    .bySimpleNaturalId(Book.class)
    .load("978-9730228236");
 
assertTrue(book.getProperties().contains("\"price\": 44.99"));

So, you don't have to create any custom Hibernate Type since you can find the right type in the hypersistence-utils project.