Use Hibernate Dynamic Update for JSON properties

Imagine having a tool that can automatically detect JPA and Hibernate performance issues. Hypersistence Optimizer is that tool!

Introduction

In this article, I’m going to explain why you should always use the Hibernate Dynamic Update feature for entities that map JSON properties.

Since Hibernate ORM does not offer support for JSON column types, we are going to use the Hibernate Types library, which provides a JsonType that allows you to map String, Map, List, JsonNode, Java Records, or POJOs on JSON columns, no matter if you are using PostgreSQL, MySQL, Oracle, SQL Server, or H2.

Domain Model

Our application requires persisting Book entities that look as follows:

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

    @Id
    @GeneratedValue
    private Long id;

    @NaturalId
    private String isbn;

    private String title;

    private String author;

    @Column(columnDefinition = "jsonb")
    @Type(type = "json")
    private String properties;
}

The properties entity attribute is mapped on a jsonb PostgreSQL column, and for this reason, it uses the JsonType from the Hibernate Types project to handle the mapping.

Updating a Hibernate entity without Dynamic Update

By default, when you modify an entity:

entityManager
    .unwrap(Session.class)
    .bySimpleNaturalId(Book.class)
    .load("978-9730228236")
    .setTitle(
        "High-Performance Java Persistence, 2nd edition"
    );

Hibernate executes an UPDATE statement that includes all the entity attributes, even the ones that didn’t get modify:

UPDATE 
    book 
SET 
    author = 'Vlad Mihalcea', 
    properties = '{
        "price":44.99,
        "reviews":[{
                "date":"2017-11-14",
                "rating":5,
                "review":"Excellent book to understand Java Persistence",
                "reviewer":"Cristiano"
            },{
                "date":"2019-01-27",
                "rating":5,
                "review":"The best JPA ORM book out there",
                "reviewer":"T.W"
            },{
                "date":"2016-12-24",
                "rating":4,
                "review":"The most informative book",
                "reviewer":"Shaikh"
            }
        }', 
    title = 'High-Performance Java Persistence, 2nd edition' 
WHERE 
    id = 1

Notice that the properties JSON object is set as well, and the larger the JSON object, the higher the performance impact of sending unneeded data.

Use Hibernate Dynamic Update for JSON properties

As I explained in this article, you can use the @DynamicUpdate annotation to instruct Hibernate that you want the UPDATE statement to be generated dynamically when flushing the Persistence Context.

So, when adding the @DynamicUpdate annotation on the Book entity:

@Entity(name = "Book")
@Table(name = "book")
@TypeDef(typeClass = JsonType.class, name = "json")
@DynamicUpdate
public class Book {
    ...
}

And, re-running the previous entity modification test case, we can see that Hibernate executes an UPDATE statement that includes only the columns that were modified:

UPDATE 
    book 
SET 
    title = 'High-Performance Java Persistence, 2nd edition' 
WHERE 
    id = 1

Much better!

I'm running an online workshop on the 9th of September about High-Performance SQL Subqueries.

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

Conclusion

As you can see, using the Hibernate Dynamic Update feature for entities that contain JSON properties is a very good idea since it allows you to avoid sending the JSON objects to the database and set the column to the very same value that was previously read.

For more details about mapping JSON columns with JPA and Hibernate, check out this article as well.

Transactions and Concurrency Control eBook

Leave a Reply

Your email address will not be published. Required fields are marked *

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