{"record":{"id":"f288306cf3e44d27","repo":"quarkusio/quarkus","slug":"cursor-based-pagination-is-not-supported-by-hibern-f28830","errorCode":null,"errorMessage":"Cursor-based pagination is not supported by Hibernate Reactive","messagePattern":"Cursor-based pagination is not supported by Hibernate Reactive","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"extensions/data/hibernate/runtime/src/main/java/io/quarkus/data/hibernate/runtime/hr/PanacheStatelessReactiveQueryImpl.java","lineNumber":93,"sourceCode":"            return PageRequest.ofPage(page.index + 1, page.size, false);\n        }\n\n        @Override\n        public ReactiveDataQuery<Entity> request(PageRequest request) {\n            // FIXME: let's hope they fix their page indices to 0-based\n            delegate.page((int) (request.page() - 1), request.size());\n            return PanacheStatelessReactiveQueryImpl.this;\n        }\n\n        @Override\n        public ReactiveDataQuery<Entity> page(long pageIndex, int pageSize) {\n            delegate.page((int) pageIndex, pageSize);\n            return PanacheStatelessReactiveQueryImpl.this;\n        }\n\n        @Override\n        public ReactiveDataQuery<Entity> cursor(long pageIndex, int pageSize) {\n            throw new UnsupportedOperationException(\"Cursor-based pagination is not supported by Hibernate Reactive\");\n        }\n\n        @Override\n        public ReactiveDataQuery<Entity> next() {\n            delegate.nextPage();\n            return PanacheStatelessReactiveQueryImpl.this;\n        }\n\n        @Override\n        public ReactiveDataQuery<Entity> previous() {\n            delegate.previousPage();\n            return PanacheStatelessReactiveQueryImpl.this;\n        }\n\n        @Override\n        public ReactiveDataQuery<Entity> first() {\n            delegate.firstPage();\n            return PanacheStatelessReactiveQueryImpl.this;","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/data/hibernate/runtime/src/main/java/io/quarkus/data/hibernate/runtime/hr/PanacheStatelessReactiveQueryImpl.java#L75-L111","documentation":"PanacheStatelessReactiveQueryImpl.cursor(pageIndex, pageSize) throws UnsupportedOperationException because cursor-based pagination is unavailable with the Hibernate Reactive stateless query delegate; only page()/nextPage() paging is supported. The method fails fast by design.","triggerScenarios":"Calling cursor(pageIndex, pageSize) on a stateless reactive Panache query instance.","commonSituations":"Shared pagination helpers written for the blocking/JDBC Panache API being applied to stateless reactive queries; keyset-pagination attempts.","solutions":["Replace cursor(...) with page(pageIndex, pageSize) and iterate with nextPage()","Implement keyset pagination manually with ordering and a where clause on the last seen key","Fall back to offset-based page() navigation"],"exampleFix":"// before\nstatelessQuery.cursor(idx, size).list();\n// after\nstatelessQuery.page(idx, size).list(); // then statelessQuery.nextPage().list()","handlingStrategy":"fallback","validationCode":"// no pre-check possible; cursor() always throws on stateless reactive queries","typeGuard":"boolean supportsCursorPagination(Object q) { return !(q instanceof PanacheStatelessReactiveQueryImpl); }","tryCatchPattern":"try { q.cursor(idx, size); } catch (UnsupportedOperationException e) { q.page(idx, size); }","preventionTips":["Restrict pagination helpers to page()/nextPage() in reactive code","Avoid porting cursor() calls from the blocking Panache API","Use explicit keyset (where id > :last) queries for cursor semantics"],"tags":["panache","pagination","cursor","stateless"],"backgroundTag":"unsupported-pagination-mode","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}