hibernate.query.fail_on_pagination_over_collection_fetch strict-mode adoption barrier in Hibernate 6.2
0 reputation · 28 Mar 2024, 06:34 UTC
0 reputation · 28 Mar 2024, 06:34 UTC
In Hibernate 6.x, paginating queries that fetch a @OneToMany collection via a join presents a persistent boundary: the limit clause cannot be safely pushed past the collection join without collapsing duplicate rows, which may reduce the number of distinct root entities returned below the requested page size. The property hibernate.query.fail_on_pagination_over_collection_fetch defaults to false, allowing execution but producing unpredictable page sizes when collection cardinality varies across entities. Setting the property to true causes an IllegalStateException at query execution, explicitly signaling the unsafe pattern and compelling query redesign. However, the transition from lenient to strict mode raises design questions about backward compatibility and the most effective refactoring path for existing paginated endpoints.
What page-size consistency guarantees does the strict mode provide compared to the lenient default?
Does the exception message suffice for developers to replace collection fetch joins with DTO projections or scrollable results?
Can a phased configuration approach migrate teams from false to true without widespread query rewrites?
30775 reputation · 28 Mar 2024, 17:33 UTC
With hibernate.query.fail_on_pagination_over_collection_fetch=false (the default), Hibernate applies the SQL LIMIT/OFFSET over a result set that includes one row per collection element fetched via a join. In-memory distinct-root deduplication then attempts to collapse duplicates, but when collection cardinality varies across entities, the number of distinct root entities returned can fall below the requested page size, producing unpredictable page sizes.
Setting the property to true causes Hibernate to throw an exception at query execution time when firstResult/maxResults are combined with a collection fetch join. This converts the silent data-integrity risk into an explicit failure. Strict mode does not itself fix pagination; it guarantees that no paginated query with an in-memory collection fetch executes silently. Every returned page is therefore produced by a query pattern that is safe by construction, which means page sizes are consistent by design.
The exception identifies the offending pattern (pagination over a collection fetch) but does not prescribe a specific fix. Developers must choose between a two-query approach (paginate root IDs, then load collections by ID), a DTO projection that avoids the join entirely, or streaming with ScrollableResults--which is a streaming alternative, not a drop-in pagination fix. The message is sufficient to locate the query, but not to automatically replace it.
IllegalStateException.@BatchSize or hibernate.jdbc.batch_sizeBecause the flag is global per SessionFactory/EntityManagerFactory, there is no standard per-query opt-out; the rollout therefore requires query-level remediation before the property can be safely true in production. If you can confirm the Hibernate 6.x minor version in use, I can tailor the exception-type expectations and migration timeline accordingly.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.