Skip to main content

Association Loading Without N+1 Queries

Evidence status: API-shape review only. The illustrative relation methods have not been executed in the current generated Java baseline, and no retained SQL/query-count result proves the N+1 outcome yet.

Problem

Load the relations required by a page without issuing one application query per parent row or loading an unrestricted object graph.

Java Path

Express the relation shape in the generated request:

Q.orders()
.selectUser(Q.usersWithIdField().selectName())
.selectLineItemList(
Q.lineItemsWithId()
.selectSkuName()
.limit(3)
)
.comment("Query orders with summary relations")
.purpose("Render the order list")
.executeForList(ctx);

The relation and selector names are illustrative. Use the exact methods emitted for the model.

Choose the smallest relation operation that answers the page:

  • scalar selectors for list labels;
  • nested selectors for detail views;
  • child limit for previews;
  • generated child counts for badges;
  • have / haveNo helpers for existence conditions.

Verification

  1. Enable SQL/query diagnostics appropriate to the runtime.
  2. Load several parents with several children each.
  3. Confirm query count does not grow linearly with the number of parents.
  4. Confirm only selected child fields and intended relations are returned.
  5. Confirm nested tenant and permission boundaries.
  6. Test parents with zero, one, and many children.

Failure Modes

SymptomFix
One child query per parentMove relation loading into the generated selection request.
Response graph is too largeSelect fewer fields, limit preview children, or split list/detail paths.
Child scope leaksApply and test nested request policy and model ownership.
Method is missingInspect generated relation/request source; do not guess or patch output.

References