Module 2C / Lesson 2C.1

N+1, Fetch Strategies, Pagination, and Geo Query

Cause the N+1 problem on purpose, fix it three ways, and show where fetch joins become wrong.

Concept

Performance lessons should start with a failure you can recognize in logs. Phase 2C deliberately creates N+1, fixes it with different tools, and then shows why the same tool can become wrong for paginated parent queries.

Task

  1. Write a broken showtime query that causes N+1 when lazy associations are touched.
  2. Add JOIN FETCH, EntityGraph, and DTO projection variants.
  3. Name the fetch-join pagination trap and prefer DTO projection or two-step page IDs.
  4. Add a native geo query with distance, start-time, and ID ordering.

Run

./gradlew dockerTest --tests "*QueryPerformanceEducationalTest"

Expected Result

  • Broken and fixed tests live in the educational package.
  • The functional API does not depend on brittle exact query counts.

Common Traps

  • Treating JOIN FETCH as universally correct.
  • Paginating over duplicated parent rows.
  • Sorting geo results without a stable tie-breaker.

Hint Ladder

Hint 1

The broken test exists so the fixed tests have a story.

Hint 2

Use loose query-count assertions, such as at most two.

Hint 3

A distance sort still needs start time and ID for stable pagination.

Solution

See QueryPerformanceEducationalTest.java and phase-2c-query-counts.txt.