Mapping Java Records to JSON columns using Hibernate

Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Wouldn’t that be just awesome?

Well, Hypersistence Optimizer is that tool! And it works with Spring Boot, Spring Framework, Jakarta EE, Java EE, Quarkus, or Play Framework.

So, enjoy spending your time on the things you love rather than fixing performance issues in your production system on a Saturday night!


In this article, I’m going to explain how we can map Java Records to JSON columns when using Hibernate.

Because Hibernate ORM does not offer built-in support for JSON, we are going to use the Hiberate Types library, which allows you to map entity attributes to JSON column types, no matter if you are using Oracle, SQL Server, PostgreSQL, or MySQL.

Java Records

As I explained in this article, Java Records are a great way to build structured data types.

In our case, we want to encapsulate the book info in the following Book data structure:

Book Java Record

To create the above Book structure, we can use the following Java Record definition:

public record BookRecord (
    String title,
    String author,
    String publisher,
    Long priceInCents,
    URL url
) {}

How to serialize Java Records to JSON using Jackson

As I explained in this article, Java Records cannot be used as JPA or Hibernate entities, but you can use them as basic attributes:

Book Record JPA entity attribute

Because Hibernate ORM does not have built-in support for Java Records, we need to provide a custom Hibernate Type to map the Java Records to the proper database column type, and one option is to persist the Java Record in a JSON column.

To make sure that the Java Records is properly marshaled to a JSON object and unmarshaled back to a Java Record, we need to change the BookRecord, like this:

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public record BookRecord (
    String title,
    String author,
    String publisher,
    Long priceInCents,
    URL url
) implements Serializable {
    public BookRecord(
        @JsonProperty("title") String title,
        @JsonProperty("author") String author,
        @JsonProperty("publisher") String publisher,
        @JsonProperty("priceInCents") String priceInCents,
        @JsonProperty("url") String url) {

The following changes are required to be done in order to properly transform the Java Record to a JSON object using Jackson:

  • the @JsonAutoDetect annotation allows Jackson to access the private fields of the Java Record when serializing or deserializing it from its String representation that’s sent to the database
  • the Serializable interface is needed because, according to the JPA specification, every entity attribute must be serializable using the Java serialization mechanism.
  • the @JsonCreator annotation was added to mark that the extra constructor can be called by Jackson to pass the Strong-based JSON attribute in order to initialize the Java Record fields.

How to map Java Records to JSON columns using Hibernate

The Hibernate Types framework has support for Oracle, SQL Server, PostgreSQL, and MySQL, so depending on the database engine and the associated JSON column type, you can use one of the following options.

For Oracle, SQL Server, MySQL, PostgreSQL, and H2, you can use the JsonType from the Hibernate Types project to map Java Records to JSON columns.

In case you’re using MySQL, then you can use the dedicated JSON column type to store the properties attributes while for PostgreSQL, you need to use the jsonb column type.

So, the Book entity would be mapped as follows:

@Entity(name = "Book")
@Table(name = "book")
    typeClass = JsonType.class, 
    defaultForType = BookRecord.class
public class Book {

    private Long id;

    private String isbn;

    @Column(columnDefinition = "JSON")
    private BookRecord properties;
    //Getters and setters omitted for brevity

Persisting Java Records to JSON columns using Hibernate

When persisting the following Book entity:

    new Book()
            new BookRecord(
                "High-Performance Java Persistence",
                "Vlad Mihalcea",

Hibernate generates the following INSERT statement:

       "title":"High-Performance Java Persistence",
       "author":"Vlad Mihalcea",

Fetching Java Records to JSON columns using Hibernate

When fetching the Book entity, we can see that we get the expected BookRecord:

Book book = entityManager

BookRecord bookRecord = book.getProperties();

    "High-Performance Java Persistence",

    "Vlad Mihalcea",

Updating Java Records

Java Records are immutable, so when we want to change the properties attribute, we have to create a new BookRecord instance, like this:

    new BookRecord(

When the Persistence Context is flushed, Hibernate generates the following UPDATE statement:

    properties = {
       "title":"High-Performance Java Persistence",
       "author":"Vlad Mihalcea",
    id = 1

Cool, right?

If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.


As you can see, Java Records are very convenient to use when you want to structure your data using immutable objects that are compact to write and flexible to customize. By adding the Jackson annotations and the extra constructor, we were able to serialize the Java Record to a JSON object when persisting the Book entity to the database and deserialize the JSON column type back to its Java Record representation.

If you want to map an entity attribute as a Java Record and persist it to a JSON column, then the Hibernate Types project will surely allow you to achieve your goal.

Transactions and Concurrency Control eBook

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.