jpa-nplus1-fix

Diagnose and fix N+1 select problems in Spring Data JPA and Hibernate code.

Updated Jul 16, 2026
One-click install
npx skills add https://github.com/jeanbisutti/poc-ia-perf --skill jpa-nplus1-fix-jeanbisutti
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: jpa-nplus1-fix
Source: https://github.com/jeanbisutti/poc-ia-perf
Command: npx skills add https://github.com/jeanbisutti/poc-ia-perf --skill jpa-nplus1-fix-jeanbisutti

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? JPA and Hibernate applications often fire one query per row when accessing lazy associations, turning a single endpoint call into dozens of SQL selects. This Skill guides the choice and application of the correct remediation for each N+1 pattern instead of applying a one-size-fits-all fix. ## Core Features & Use Cases - Decision-table remediation: Selects the right fix based on three triage questions (read-only vs managed entities, pagination, number of collections), covering DTO projections, JOIN FETCH, @EntityGraph, batch fetching, the two-query pattern, and SUBSELECT. - Root-cause hygiene: Enforces LAZY mappings on to-one associations, disables Open-Session-In-View, and sets a global batch-fetch safety net to prevent whole classes of N+1. - Pitfall and version guidance: Covers the HHH000104/HHH90003004 pagination trap, MultipleBagFetchException, inverse @OneToOne lazy loading, and Hibernate 5 to 6 migration differences. - Use Case: A Spring Boot endpoint returns a list of teams and fires 11 SELECT statements instead of 1; the Skill identifies it as a read-only list and applies a DTO constructor projection so the query count stays constant. ## Quick Start Ask the assistant to fix the N+1 select problem in a specific JPA repository method or REST endpoint using this skill.

Frequently Asked Questions about jpa-nplus1-fix

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I fix N+1 queries in Spring Data JPA?

First triage the call site: for read-only endpoints use a DTO projection, for managed entities without pagination use JOIN FETCH or @EntityGraph, and for paginated collection fetches use the two-query pattern or batch fetching. Also make all to-one associations LAZY and disable open-in-view.

What is the best fix for N+1 on a paginated collection query?

Use the two-query pattern: paginate entity IDs first with a clean SQL LIMIT, then fetch entities with their collection for just those IDs. Batch fetching via default_batch_fetch_size is a pagination-safe alternative. Never combine JOIN FETCH of a collection with Pageable.

Does JOIN FETCH work with pagination in Hibernate?

No. Combining a collection JOIN FETCH with Pageable or setMaxResults makes Hibernate drop the SQL LIMIT and paginate in memory, logging HHH000104 (Hibernate 5) or HHH90003004 (Hibernate 6). Use the two-query pattern or batch fetching instead.

Why does LazyInitializationException happen and how should I fix it?

It happens when a lazy association is accessed outside an open Hibernate session. Do not fix it by enabling open-in-view or enable_lazy_load_no_trans, which hide an N+1; instead add an explicit fetch at the call site via JOIN FETCH, an entity graph, or a DTO projection.

How do I resolve MultipleBagFetchException in Hibernate?

MultipleBagFetchException occurs when join-fetching two List collections at once. The robust fix is one query per collection, letting the persistence context stitch them onto the same parent instances. Avoid blindly switching to Set, which creates a cartesian product on large data.

When should I use DTO projections instead of entity graphs?

Use DTO projections whenever the use case is read-only, such as API responses or exports, because no managed entities means an N+1 is structurally impossible. Use entity graphs or JOIN FETCH only when the caller needs managed entities it will modify.