Hibernate: N+1 selects is the default, and join fetch is the cure

Loading a list then touching a lazy association issues one extra query per row. It passes every test with three rows and melts in production.

Code
// N+1: 1 query for orders, then 1 per order for items
List<Order> orders = em.createQuery("select o from Order o", Order.class).getResultList();
orders.forEach(o -> o.getItems().size());

// One query instead:
List<Order> orders = em.createQuery(
        "select distinct o from Order o join fetch o.items", Order.class).getResultList();
Output
Before: select ... from orders            (1)
        select ... from order_items where order_id=?  (x 500)
After:  select ... from orders o join order_items i on ...   (1)
Advertisement

Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.

Published 2026-08-11