ORM pitfalls
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
- Detect N+1 queries from SQL logs or a query counter in tests.
- Fix N+1 with fetch joins, entity graphs, or projections.
- Explain lazy vs eager loading and why
LazyInitializationExceptionhappens. - Explain why fetch-joining collections with pagination is dangerous and apply a safe alternative.
Lessons
Lab and exercises
Lab
JNR-032-LAB1 · Fix the order list
Outcomes: 1–4 · Time: ~3 h
- Run the provided order-history endpoint with 100 orders; record the number of SQL statements (101).
- Write a test with a query counter asserting at most 2 queries; it must fail first.
- Fix with a fetch join, entity graph, or projection; keep pagination safe (page ids, then load).
- Disable Open Session in View and make sure no
LazyInitializationExceptionappears. - 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)
| ID | Outcome | Task |
|---|---|---|
| JNR-032-EX01 | 1 | From a provided SQL log, count the queries and point out the repeated one. |
| JNR-032-EX02 | 2 | Fix the same endpoint twice: with join fetch and with @EntityGraph. |
| JNR-032-EX03 | 2 | Replace entity loading with a projection for an order-summary list. |
| JNR-032-EX04 | 3 | Explain when LazyInitializationException happens and give two correct fixes (and one wrong). |
| JNR-032-EX05 | 4 | Write the two-step query that pages orders with their lines safely. |
| JNR-032-EX06 | 1-4 | Diagnose a slow endpoint from provided logs; write cause, evidence, and fix. |
Show solutions
- EX01 One
select ... from ordersfollowed by N identicalselect ... from order_line where order_id=?; N+1. - EX02
select distinct o from Order o join fetch o.linesand@EntityGraph(attributePaths = "lines"). - EX03
select new ...OrderSummary(o.id, o.createdAt, c.name) from Order o join o.customer creturned as aPage. - 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
EAGERglobally. - 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.
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.