Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

preventing N+1 selects in JPA [duplicate]

I have JPA entities Order with a ManyToOne relation to Customer. It is bidirectional, so that Customer also has a OneToMany field orders. Both of the relations use EAGER fetching (or are in the OpenJPA fetchplan).

When I select from Order, I get 1 select for orders and N selects for the Customer.orders field. To my surprise this problem is present with OpenJPA, EclipseLink and Hibernate, even when I use JOIN FETCH (which does work in a unidirectional case).

Is there a good way to solve this? Are there any solutions for solving N+1 select problems for more complex graphs?

EDIT: Results of my own research: - For OpenJPA (which I'm using) I don't know a solution yet - For Hibernate @Fetch(FetchMode.SUBSELECT) solves the problem. Using @BatchSize also helps, this selects a given number of customer.orders fields at the same time. - For EclipseLink I found a similar feature @BatchFetch(value=BatchFetchType.IN) but it does not help in this case, I suppose it cannot efficiently handle this in a bidirectional relation.

like image 311
Henno Vermeulen Avatar asked Nov 15 '12 15:11

Henno Vermeulen


People also ask

How can n 1 problems be prevented?

Alternatively, one could get all wheels and perform the lookups in memory: SELECT * FROM Wheel; This reduces the number of round-trips to the database from N+1 to 2. Most ORM tools give you several ways to prevent N+1 selects.

Why does JPA return duplicate rows?

Issue with @Id column, If we check closely, @Id column value is same for all the rows. Hence hibernate/JPA not able to get different records, it just get 1st record with this @Id and return duplicate records of it. Solution - Use @IdClass with columns which result in unique row instead of duplicate row.

What is the N 1 query problem?

What is the N+1 query problem? The N+1 query problem is one of the common performance antipatterns in ORMs. It happens when a query is executed on each result of the previous query, in other words, when an application gets data from the database and then loop through the result of that data.


1 Answers

Have a look at: What is SELECT N+1? as there lots of good info there.

If your using Hibernate: Hibernate - Chapter 19: Improving Performance - Fetching Strategies

My own personal solution is to use native SQL and tmp ids table that is because generally IMHO the N+1 select problem is mainly a problem with batch processing. Otherwise lazy loading (typically N+1 solution) can be beneficial to performance.

like image 196
Adam Gent Avatar answered Sep 30 '22 10:09

Adam Gent