Hibernate N+1 Problem

The N+1 query problem is said to occur when an ORM, like hibernate, executes 1 query to retrieve the parent entity and N queries to retrieve the child entities. As the number of entities in the database increases, the queries being executed separately can easily affect the performance of the application.


The relation between user_details and address is a one-many mapping from user_details(id) to address(user_id). That means a user can have many addresses.

Public class UserDetails{  
---
-....

@OneToMany(cascade = CascadeType.ALL, mappedBy = "userDetails")
private List<Address> addresses;

}

Public class Address

{ ---

.....

@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)

@JoinColumn(name = "user_id", referencedColumnName = "id")

private UserDetails userDetails;

}

Now let us query for the name contains on user_details table with repository function.

@Repository

public interface UserDetailsRepository extends JpaRepository<UserDetails, String> {

   List<UserDetails> findByNameContaining(String text);

}

When we call the function this will generate two different queries one to fetch the from user_details based on name and the other on addresses using user_id . As of now, we have only two users the additional queries are only two. If the number of matching queries increases the additional queries also increase.

Hibernate: select userdetail0_.id as id1_1_, userdetail0_.created_at as created_2_1_, userdetail0_.email as email3_1_, userdetail0_.mobile_number as mobile_n4_1_, userdetail0_.name as name5_1_, userdetail0_.updated_at as updated_6_1_ from user_details userdetail0_ where userdetail0_.name like ? escape ?

Hibernate: select addresses0_.user_id as user_id10_0_0_, addresses0_.id as id1_0_0_, addresses0_.id as id1_0_1_, addresses0_.address1 as address2_0_1_, addresses0_.address2 as address3_0_1_, addresses0_.city as city4_0_1_, addresses0_.country as country5_0_1_, addresses0_.created_at as created_6_0_1_, addresses0_.state as state7_0_1_, addresses0_.street as street8_0_1_, addresses0_.updated_at as updated_9_0_1_, addresses0_.user_id as user_id10_0_1_ from address addresses0_ where addresses0_.user_id=?

Hibernate: select addresses0_.user_id as user_id10_0_0_, addresses0_.id as id1_0_0_, addresses0_.id as id1_0_1_, addresses0_.address1 as address2_0_1_, addresses0_.address2 as address3_0_1_, addresses0_.city as city4_0_1_, addresses0_.country as country5_0_1_, addresses0_.created_at as created_6_0_1_, addresses0_.state as state7_0_1_, addresses0_.street as street8_0_1_, addresses0_.updated_at as updated_9_0_1_, addresses0_.user_id as user_id10_0_1_ from address addresses0_ where addresses0_.user_id=?

How to fix it?

Use Join

Use EntityGraphs






Comments

Popular posts from this blog

Java 8 : Find the number starts with 1 from a list of integers

Optional Vs Null Check

How to prevent Singleton Class from Reflection and Serialization