Constructor based HQL to improve performance

1. Introduction

In normal scenarios, in an application using Hibernate, we don’t bother retrieving the whole entity with all its properties even though we don’t need all of them for a particular use case. A single entity might have 30 properties, while we might just need a few to be set in our web service response or display to the user. When in a scenario thousands of records are liable to retrieved based on our query, think of the unused fields we are heavily jamming our application with, which ultimately lead to a huge performance hit.

To deal with this, HQL/JPA provides us with a select new constructor call, which are often used for reporting queries, which allows the developer to select aggregated values as well. For example –

We will soon get familiar on how to use it

Reporting Queries are the same as HQL, except that we are just selecting the fields that are required (and not the whole of mapped entity) and can also use aggregate functions. Along with this, we also avoid the overhead of retrieved entities getting cached in the persistent context and automatic dirty checking using constructor based HQL. A huge improvement in the performance can be noticed as compared to the traditional retrieval technique with Hibernate.

2. Implementation

To start implementing it, let’s first make sure we have the right HQL in-place to be queried.

In the search user implementation, we have the following method written in DAO layer, in which we have decided to retrieve just the userId and userName as per the requirement. We are not bothered about other entities.

Based on this, we need to create the appropriate constructor in the entity class, which will return the User object reference with just the required properties that we are retieving.

3. Advantages

With normal HQL (non-constructor based), Hibernate always adds the entities, returned as a result of HQL query execution, to the persistence context cache or may be the second-level cache, where it manages the stuffs along with maintaining uniqueness of the entities.

With our constructor-based HQL implementation, when the query is executed, all instances returned by your query are in transient state, which means that the query doesn’t return persistent entity instances and Hibernate no more adds any persistent object to the persistence context cache. This means that no object will be watched for dirty state either.

4. Disadvantages

While the advantages of this approach could be more noticed, such queries have a disadvantage too. Such queries result in transient/non-persistent resultant objects which lose the capability to use the Hibernate cache, which becomes a crucial decision to take, considering sometimes the overhead of remote communication with the database system.

5. Download the source code

Receive our updates to your inbox

Get more stuff like this
in your inbox

Subscribe to our mailing list and get interesting stuff and updates to your email inbox.