Loading published curriculum…

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

  1. 01Load twenty tasks and access their owners while counting SQL statements.
  2. 02Apply a focused fetch plan and repeat with distinct owners.
  3. 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.

  1. 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.
  2. 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.
  3. 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?

Choose one answer

BUILD IT YOURSELF

Load twenty tasks and access their owners while counting SQL statements.

  1. 1.Load twenty tasks and access their owners while counting SQL statements.
  2. 2.Apply a focused fetch plan and repeat with distinct owners.
  3. 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.

Go deeper · official references