Skip to content
Ameen Abozaid
JNR-032

ORM pitfalls

  • 7 Lessons
  • 3 h practice (estimate)
On this page 8 topics

Overview

Topics

  • N+1 queries
  • lazy/eager loading
  • pagination pitfalls
  • fetching strategies

Learn first

3 h of practice (estimate)

Learning outcomes

  1. Detect N+1 queries from SQL logs or a query counter in tests.
  2. Fix N+1 with fetch joins, entity graphs, or projections.
  3. Explain lazy vs eager loading and why LazyInitializationException happens.
  4. Explain why fetch-joining collections with pagination is dangerous and apply a safe alternative.

Lessons

  1. 01The N+1 problem
  2. 02Fetch joins and entity graphs
  3. 03Lazy loading and its exception
  4. 04Pagination with collections
  5. 05Open Session in View: why to turn it off
  6. 06Demo: catching N+1 with a query-count test
  7. 07Demo: fixing lazy loading without Open Session in View

Lab and exercises

Lab

JNR-032-LAB1 · Fix the order list

Outcomes: 1–4 · Time: ~3 h

  1. Run the provided order-history endpoint with 100 orders; record the number of SQL statements (101).
  2. Write a test with a query counter asserting at most 2 queries; it must fail first.
  3. Fix with a fetch join, entity graph, or projection; keep pagination safe (page ids, then load).
  4. Disable Open Session in View and make sure no LazyInitializationException appears.
  5. Re-run the test; it passes.

Acceptance: test fails before, passes after; at most 2 queries for 100 orders.

Exercises (assessment: diagnose a slow endpoint from logs)

IDOutcomeTask
JNR-032-EX011From a provided SQL log, count the queries and point out the repeated one.
JNR-032-EX022Fix the same endpoint twice: with join fetch and with @EntityGraph.
JNR-032-EX032Replace entity loading with a projection for an order-summary list.
JNR-032-EX043Explain when LazyInitializationException happens and give two correct fixes (and one wrong).
JNR-032-EX054Write the two-step query that pages orders with their lines safely.
JNR-032-EX061-4Diagnose a slow endpoint from provided logs; write cause, evidence, and fix.
Show solutions
  • EX01 One select ... from orders followed by N identical select ... from order_line where order_id=?; N+1.
  • EX02 select distinct o from Order o join fetch o.lines and @EntityGraph(attributePaths = "lines").
  • EX03 select new ...OrderSummary(o.id, o.createdAt, c.name) from Order o join o.customer c returned as a Page.
  • EX04 Raised when a lazy relation is read after the context closed. Fixes: fetch join or entity graph; DTO built in the transaction. Wrong fix: switch to EAGER globally.
  • EX05 Step 1: page of order ids; step 2: select distinct o from Order o join fetch o.lines where o.id in :ids.
  • EX06 Look for repeated selects, missing paging, or OSIV; cite log lines as evidence.

Quiz

Outcomes: O1 detect N+1 · O2 fix N+1 · O3 lazy loading and its exception · O4 pagination with collections and OSIV.

A self-check for you: nothing is graded, saved or sent anywhere. Choose an answer, then check it. You can try again as often as you like.

  1. 1100 orders loaded with N+1 on lines cause:O1
  2. 2A good way to catch N+1 in tests:O1
  3. 3Which fixes N+1?O2
  4. 4@EntityGraph on a repository method:O2
  5. 5LazyInitializationException occurs when:O3
  6. 6The default fetch of @OneToMany is:O3
  7. 7The wrong "fix" for a lazy exception is:O3
  8. 8Fetch-joining a collection with paging makes Hibernate:O4
  9. 9Safe paging with collections:O4
  10. 10Open Session in View should be:O4

Practical part

Six exercises JNR-032-EX01 to EX06 plus the lab; the assessment is diagnosing a slow endpoint from logs (EX06). Pass: correct cause, evidence, and fix in EX06, at least five of six exercises correct, lab test failing before and passing after.

Common mistakes

Switching everything to EAGER; leaving Open Session in View enabled.

Assessment

Diagnose a slow endpoint from logs.

Career relevance

Common production issue; MID-021 goes deeper.

Type to search levels, phases, modules and lessons.