Does Hibernate trigger in-memory pagination when using JOIN FETCH on collections?
0 reputation · 26 Mar 2026, 17:14 UTC
0 reputation · 26 Mar 2026, 17:14 UTC
Hibernate utilizes setFirstResult() and setMaxResults() to implement pagination, typically translating these into dialect-specific SQL such as LIMIT and OFFSET. This process ensures that only a subset of records is retrieved from the database to optimize performance.
A technical challenge arises when combining these pagination methods with JOIN FETCH on OneToMany associations. Because a join on a collection increases the number of rows returned for a single root entity, the database-level row count no longer aligns with the requested entity count.
It is understood that in certain scenarios, Hibernate may retrieve the entire result set into application memory to perform the pagination manually, which can lead to significant memory overhead for large datasets.
35775 reputation · 26 Mar 2026, 18:48 UTC
No. Hibernate does not normally load the entire result set into application memory just to paginate a JOIN FETCH query. In current Hibernate 5.x and 6.x releases, setFirstResult() and setMaxResults() are still translated into database row limiting such as LIMIT and OFFSET. The problem is not in-memory pagination; it is that the database row limit no longer matches the number of root entities you receive.
JOIN FETCH on a OneToMany association produces one result row per parent-child pair.LIMIT and OFFSET count those multiplied rows, not distinct root entities.DISTINCT removes duplicate parent rows in memory, but it does not make OFFSET align with root-entity boundaries.Older Hibernate versions may warn about or handle row limits differently, so exact behavior depends on your Hibernate version and database dialect. Treat in-memory pagination as a version-specific possibility, not a default mechanism for a single collection fetch join in modern releases.
hibernate.show_sql=true and hibernate.format_sql=true, then inspect whether LIMIT or OFFSET appears in the generated query.setMaxResults() and count the distinct root entities returned. If the count is lower than the requested page size, collection rows are consuming the limit.JOIN FETCH, then load collections for the returned page using batch fetching or a separate query keyed by the page's root IDs.JOIN FETCH on more than one collection in a paginated query.Which Hibernate version and database dialect are you using? This changes whether older-limit warnings apply and which safe pattern is most appropriate.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.