Hibernate Query pagination with JOIN FETCH and database limit/offset
0 reputation · 12 Aug 2024, 23:19 UTC
0 reputation · 12 Aug 2024, 23:19 UTC
The goal is to configure Hibernate ORM pagination via setFirstResult and setMaxResults so that LIMIT/OFFSET is generated by the dialect and the database applies paging before results are materialized.
The queries use JOIN FETCH to load an entity graph in a single round trip. Dialect support for limit/offset can vary by query structure, and Hibernate may fall back to loading the full result set when it considers database-level pagination unsafe. The exact permission boundary for when fallback is allowed is unclear.
Assuming recent Hibernate ORM versions, what configuration controls whether in-memory pagination is permitted for JOIN FETCH queries? How is dialect capability evaluated for a specific query shape? What is the documented behavior when limit/offset cannot be applied safely to a fetch join?
33775 reputation · 13 Aug 2024, 00:10 UTC
The behavior is governed by the boolean property hibernate.query.fail_on_pagination_over_collection_fetch (default false). When false, Hibernate allows in‑memory pagination and logs warning HHH000104. Setting it to true forces Hibernate to throw a QueryException instead of falling back.
Hibernate first checks whether the underlying dialect supports LIMIT/OFFSET. If supported, it then inspects the query shape: any JOIN FETCH on a collection‑valued association marks the query as unsafe for database‑level pagination because the join would produce a Cartesian product that multiplies root‑entity rows. For such queries the dialect’s limit capability is ignored and the fallback path is taken. Single‑ended fetches (ManyToOne/OneToOne) do not change the row count, so the dialect can safely apply LIMIT/OFFSET.
When the unsafe condition is detected, Hibernate:
setFirstResult() and setMaxResults() by slicing the list in memory.HHH000104: firstResult/maxResults specified with collection fetch; applying in memory!.This can lead to excessive memory usage and OutOfMemoryError for large datasets.
hibernate.show_sql=true) and confirm that the generated SQL lacks LIMIT/OFFSET for a paginated query with a collection fetch join.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.