quarkusio/quarkus · error · UnsupportedOperationException

Cursor-based pagination is not supported by Hibernate Reacti

Error message

Cursor-based pagination is not supported by Hibernate Reactive

What it means

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.

Source

Thrown at extensions/data/hibernate/runtime/src/main/java/io/quarkus/data/hibernate/runtime/hr/PanacheStatelessReactiveQueryImpl.java:93

            return PageRequest.ofPage(page.index + 1, page.size, false);
        }

        @Override
        public ReactiveDataQuery<Entity> request(PageRequest request) {
            // FIXME: let's hope they fix their page indices to 0-based
            delegate.page((int) (request.page() - 1), request.size());
            return PanacheStatelessReactiveQueryImpl.this;
        }

        @Override
        public ReactiveDataQuery<Entity> page(long pageIndex, int pageSize) {
            delegate.page((int) pageIndex, pageSize);
            return PanacheStatelessReactiveQueryImpl.this;
        }

        @Override
        public ReactiveDataQuery<Entity> cursor(long pageIndex, int pageSize) {
            throw new UnsupportedOperationException("Cursor-based pagination is not supported by Hibernate Reactive");
        }

        @Override
        public ReactiveDataQuery<Entity> next() {
            delegate.nextPage();
            return PanacheStatelessReactiveQueryImpl.this;
        }

        @Override
        public ReactiveDataQuery<Entity> previous() {
            delegate.previousPage();
            return PanacheStatelessReactiveQueryImpl.this;
        }

        @Override
        public ReactiveDataQuery<Entity> first() {
            delegate.firstPage();
            return PanacheStatelessReactiveQueryImpl.this;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Replace cursor(...) with page(pageIndex, pageSize) and iterate with nextPage()
  2. Implement keyset pagination manually with ordering and a where clause on the last seen key
  3. Fall back to offset-based page() navigation

Example fix

// before
statelessQuery.cursor(idx, size).list();
// after
statelessQuery.page(idx, size).list(); // then statelessQuery.nextPage().list()
Defensive patterns

Strategy: fallback

Validate before calling

// no pre-check possible; cursor() always throws on stateless reactive queries

Type guard

boolean supportsCursorPagination(Object q) { return !(q instanceof PanacheStatelessReactiveQueryImpl); }

Try / catch

try { q.cursor(idx, size); } catch (UnsupportedOperationException e) { q.page(idx, size); }

Prevention

When it happens

Trigger: Calling cursor(pageIndex, pageSize) on a stateless reactive Panache query instance.

Common situations: Shared pagination helpers written for the blocking/JDBC Panache API being applied to stateless reactive queries; keyset-pagination attempts.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/f288306cf3e44d27. Report an issue: GitHub.