14 · Hibernate and Spring Data JPA in depth / LESSON 68 OF 102
Lazy loading, N+1 queries, and fetch plans
A correct result can still be expensive if loading each row triggers another query.
Before this lesson: Cascade, orphan removal, and many-to-many design
Understand the topic
N+1 commonly appears when a list query loads N entities and traversing a relationship loads each associated object separately. Count SQL statements under realistic data. Lazy loading requires an available persistence context; disabling open-in-view exposes accidental web-layer database access.
Use a fetch join, entity graph, or DTO projection for the specific read. Avoid fetching multiple large collections into one Cartesian result. Collection fetch joins and pagination require care; page identifiers first or choose a projection-based read.
EXAMPLE · JAVA
Repository method fragment
@org.springframework.data.jpa.repository.EntityGraph(attributePaths = "owner")
java.util.List<Task> findByDone(boolean done);What to expect
Inside a Task JpaRepository with a mapped owner association, requests an owner fetch plan for this query. Inspect actual SQL and cardinality.
YOUR TURN
Put it into practice
- 01Load twenty tasks and access their owners while counting SQL statements.
- 02Apply a focused fetch plan and repeat with distinct owners.
- 03Verify: The query count stays bounded and the response does not depend on an open persistence context in the view.
Pass a quiz or complete a lab to check today’s streak. Each lesson counts once per day, including when you review it later.
UNDER THE HOOD
Build the mental model
A correct result can still be expensive if loading each row triggers another query.
- 01N+1 commonly appears when a list query loads N entities and traversing a relationship loads each associated object separately. Count SQL statements under realistic data. Lazy loading requires an available persistence context; disabling open-in-view exposes accidental web-layer database access.
- 02Use a fetch join, entity graph, or DTO projection for the specific read. Avoid fetching multiple large collections into one Cartesian result. Collection fetch joins and pagination require care; page identifiers first or choose a projection-based read.
- 03Trace the example: Inside a Task JpaRepository with a mapped owner association, requests an owner fetch plan for this query. Inspect actual SQL and cardinality.
A mistake worth avoiding
Rendering twenty task cards triggers twenty extra owner queries.
DEBUGGING ROOM
Something broke. Where do you look?
Rendering twenty task cards triggers twenty extra owner queries.
Before revealing the diagnosis, write down your first investigation step.
CHECK YOUR UNDERSTANDING
Is setting every association to EAGER a reliable N+1 solution?
BUILD IT YOURSELF
Load twenty tasks and access their owners while counting SQL statements.
- 1.Load twenty tasks and access their owners while counting SQL statements.
- 2.Apply a focused fetch plan and repeat with distinct owners.
- 3.Reproduce this failure, then repair it: Rendering twenty task cards triggers twenty extra owner queries.
Acceptance checklist
Lab completion is your self-report. Knowledge checks do not certify project quality.
RETRIEVE IT FROM MEMORY
Is setting every association to EAGER a reliable N+1 solution?
Revisit this lesson in three days after a successful check or lab.
Ready for the next step?
The query count stays bounded and the response does not depend on an open persistence context in the view.
Reading is separate from passing a knowledge check or completing a lab.