Use Hibernate Dynamic Update for JSON properties
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!
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 Hypersistence Utils 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.
For Hibernate 6, the mapping will look as follows:
@Entity(name = "Book") @Table(name = "book") public class Book { @Id @GeneratedValue private Long id; @NaturalId private String isbn; private String title; private String author; @Type(JsonType.class) @Column(columnDefinition = "jsonb") private String properties; }
And for Hibernate 5, like this:
@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; @Type(type = "json") @Column(columnDefinition = "jsonb") private String properties; }
The properties
entity attribute is mapped on a jsonb
PostgreSQL column, and for this reason, it uses the JsonType
from the Hypersistence Utils 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") @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!
If you enjoyed this article, I bet you are going to love my Book and Video Courses as well.
And there is more!
You can earn a significant passive income stream from promoting all these amazing products that I have been creating.
If you're interested in supplementing your income, then join my affiliate program.
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.
