GORM Pagination API and Hibernate SQL Execution: Bounding Large Datasets with max and offset
0 reputation · 04 Feb 2021, 01:18 UTC
In current Grails releases, the list method maps max and offset to Hibernate's setMaxResults and setFirstResults, producing SQL LIMIT/OFFSET clauses. However, the interaction between GORM's convenience binding and Hibernate's execution model raises unresolved questions for deep pagination.
As offset values grow, the database must scan and discard skipped rows before returning the requested page, leading to linear performance degradation. Additionally, when ordering by non-unique columns, row order is not guaranteed between queries, which can cause duplicates or gaps across page boundaries. GORM does not provide first-class keyset pagination, leaving a design decision between simple offset paging and manual seek-based queries. Furthermore, if max is omitted from the params map, the result set may remain unbounded unless a default limit is explicitly configured.
Given these constraints, should the GORM pagination layer enforce a default max to prevent unbounded queries, or is that responsibility better left to explicit controller configuration? When sorting by non-unique properties, what secondary tie-breaker strategy is required to ensure stable pagination across consecutive GORM list calls? How does the absence of native keyset pagination in GORM affect the choice between offset-based bounding and manual seek queries for large datasets?