Solving N+1 Query Problem in Spring Boot with Hibernate

Recently, while working with Spring Boot and Hibernate, I came across a very common performance issue called the N+1 query problem. At first, everything looked fine. I was fetching all orders using: List<Order> orders = orderRepository.findAll(); This runs just one query on the orders table. But later, when I tried to access the customer information inside a loop: for (Order order : orders) { System.out.println(order.getCustomer().getName()); } Hibernate started firing one extra query for each order because of lazy loading. So if there are 100 orders, instead of 1 query, it becomes 101 queries. That’s when I understood how easily performance can be affected if we don’t pay attention to fetch strategies. To solve this, I explored a few approaches: 1. JOIN FETCH (Most Common) Fetch parent and child entities in a single query: @Query("SELECT o FROM Order o JOIN FETCH o.customer") List<Order> findAllOrdersWithCustomer(); This generates: SELECT o.*, c.* FROM orders o JOIN customer c ON o.customer_id = c.id; Now only 1 query runs instead of 101. 2. @EntityGraph A cleaner Spring Data JPA solution: @EntityGraph(attributePaths = {"customer"}) List<Order> findAll(); This tells Hibernate to fetch customer along with orders. Very clean and avoids custom JPQL. 3. Batch Fetching (@BatchSize) Very useful for @OneToMany relationships. @OneToMany(mappedBy = "customer") @BatchSize(size = 20) private List<Order> orders; Instead of firing one query per customer, Hibernate fetches in batches: SELECT * FROM orders WHERE customer_id IN (1,2,3,...20) This significantly reduces query count. 4. DTO Projection Best for API responses when only selected fields are needed. @Query(""" SELECT new com.example.dto.OrderDto( o.id, c.name ) FROM Order o JOIN o.customer c """) List<OrderDto> findAllOrderDtos(); This is fast, efficient, and avoids unnecessary entity loading. Learning things like this makes backend development really interesting for me — sometimes the code works perfectly, but under the hood it may still be inefficient. #SpringBoot #Hibernate #Java #BackendDevelopment #SoftwareEngineering #LearningJourney

To view or add a comment, sign in

Explore content categories