Issue N + 1 query in Hibernate

Tram Ho

Hibernate is a popular ORM (Object Relational Mapping) framework in the Java programming language ecosystem. Being a common framework does not mean there are no difficult elements to use.
ORMs are familiar to programmers and many programmers have used them to quickly launch applications and manipulate databases without having to write database query statements. But it can lead to a lot of problems if programmers are not familiar with the basic functions of the framework. And the problem of n + 1 query is such a problem.
This is also a question I was asked in an interview. There is a great article on how to solve this problem and I would like to share it again with you.

1. Issue n + 1 queries

If you’ve used Hibernate (or any other ORM framework), chances are you’ve encountered the notorious n + 1 problem over and over again.
N + 1 query problem occurs when while you load data in FetchType.LAZY mode in One-to-Many in parent-child relationship: 1 query to retrieve n parent objects
It takes n more queries (one for each lookup object) to retrieve sub objects

2. Illustrative example

Environment is: Spring Boot, JPA (Hibernate), H2 database. We created a database with 5 authors and 25 books. Each author assigns with 5 books

It is part of the code to print out the author’s name and the number of related books. Here we will have logs:

As you can see there is a query that is executed to retrieve the author list and then each individual query is executed to retrieve books for each author, resulting in an additional 6 queries being executed. . This is the default behavior in Hibernate, in my opinion it is fine as long as you give the book to an author.
But now consider the impact of this problem in an actual application, when the data is not on the same server and there are thousands of records. It will greatly improve your performance when you do it.

3. Use Fetch Mode

In Hibernate provide annotations (anotation) Fetch (…) can be used to determine how to fetch a set of related objects (such as loading book objects for author objects in the above example)

FetchMode.SUBSELECT

  • “use a subquery to load additional collections” * – SUBSELECT
    Using Fetch (FetchMode.SUBSELECT) will only give an additional query to retrieve books.
    Modify the Author.java class as follows:

And now we will have the log:

We can see only two queries being executed, one for retrieving the author list, the other for retrieving books related to these authors. JOIN FETCH What if we wanted to fetch all authors and their books in a single query?
If I wanted to write a query for this purpose, I would join the tables together.
Do it in a way ORM is familiar to developers using the Query annotation.
Re-use the AuthorDataService.java class as follows:

Now we can log as follows:

The problem has been solved! Mostly, using ** JOIN FETCH ** solves the problem of multiple queries using joins but it returns duplicate records for each Author. But that is what joins are supposed to do

Performing the above query produces the following result, where each author is duplicated with their data

The problem with repeating the record is to add DISTINCT to the query:

Logs:

4. Conclusion

So through this article I have presented to you query n + 1 query as well as the solution in Hibernate. Thank you for taking the time to read and hopefully it will help you! Reference: https://medium.com/@mansoor_ali/hibernate-n-1-queries-problem-8a926b69f618

Share the news now

Source : Viblo