Lazy Loading of JPA attributes with Hibernate

Last Updated:  July 14, 2020 | Published: June 24, 2018

Modeling your domain model with JPA is quite easy and for a smaller amount of data, you can easily rely on the default configuration of JPA. But when it comes to performance issues in your application you need a deeper understanding of JPA  and Hibernate. One big performance boost could be Lazy Loading. When it comes to Lazy Loading, most of the developers think of using this optimization for entity relationships like @OneToMany/@OneToOne/@ManyToMany, which is commonly used to disable the loading of the whole entity graph within fetching one entity. Another, not widely used, optimization is the Lazy Loading of attributes for a JPA entity, which I'll demonstrate in this blog post.

JPA entity setup for lazy loading

Let's assume you are writing a web application and you want to store the file uploads of your users to your database (notwithstanding the fact this is a good idea or not).

A possible JPA entity for this task could look like the following:

One possible use case might be to inspect all uploaded files from a user in Java code. Therefore you don't want to load all the byte array representation of the files in your memory at first. To lazy load the fileContent you have to modify the attribute and add the following @Basic(fetch = FetchType.LAZY) annotation:

With just this annotation, Hibernate wouldn't be able to lazy load the file content per default. To get this running you have to enhance the bytecode of your JPA entity. Use the following Maven plugin from Hibernate to achieve this:

After running mvn clean compile or mvn clean package/install the FileUpload class file contains some more fields and methods with the prefix $$_hibernate_ like the following:

With this enhancement, Hibernate is now able to lazy load access to the fileContent. To demonstrate this, I'll use a small Spring Boot app where I store the application.properties  file in an in-memory database (H2) on startup and query for it in another class. For visualization of the lazy loading, I enabled the logging of the SQL statements:

When running the Spring Boot application the following log is produced:

You can see that Hibernate created three SQL queries, one for the insert, another for the select. The third is for accessing the fileContent.

The source code for this demo project is available on GitHub.

PS: This was one of the many great tips/hints/insights about JPA and Hibernate I got from the excellent book High-Performance Java Persistence from @vlad_mihalcea. Read my review of his video course here.

Happy Lazy Loading with JPA,

Phil

>