Jpa OneToOne N+1 Issue#
Fix N+1 Issue With OneToOne Relationship in Jpa.#
- In Jpa if we define
OneToOnerelationship as below.
| CustomerEntity.java | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | |
| LoyaltyCardEntity.java | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | |
- Then when we query to get a
CustomerEntitty, we will see in the log that every time we get aLoyaltyCardEntity, a hibernate query will be generated base on how manyLoyaltyCardin the list.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |
-
So how do you think if there are 10000 customers with 10000 loyaltycards. This will make the database execute thousands queries and it will lead to bad performance.
-
To avoid it, we will use the
Entity Graphswhich are a feature introduced in JPA 2.1 that provides a more sophisticated method of dealing with performance loading. They provide a way to define which attributes (fields) of an entity should be loaded from the database when the entity is fetched. This can be particularly useful when dealing with entities that have relationships with other entities. -
The main goal of the JPA
Entity Graphis to improve the runtime performance when loading the entity’s related associations and basic fields1. The JPA provider loads all the graphs in one select query and then avoids fetching associations with moreSELECTqueries. This is considered a good approach for improving application performance. -
In Spring Boot, we can define an
Entity Graphusing a combination of@NamedEntityGraphand@EntityGraphannotations. We can also define ad-hoc entity graphs with just theattributePathsargument of the@EntityGraphannotation.
With @NamedEntityGraph#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | |
- Then in the
repositorywe just define thefindAllmethod with@EntityGraphannotation.
| CustomerRepository.java | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | |
Without @NamedEntityGraph#
- Then in the
repositorywe just define thefindAllmethod with@EntityGraphannotation usingattributePaths.
| CustomerRepository.java | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
-
With this approach, we don't need to use
@NamedEntityGraphannotation in theCustomerEntity. -
References: