quarkusio/quarkus · error · UnsupportedOperationException

Stateless operations not supported

Error message

Stateless operations not supported

What it means

The quarkus-data-hibernate runtime's ManagedReactiveOperations implements the HR (hibernate-reactive) operations contract, but its getStatelessSession(Class) method is intentionally unimplemented: stateless session support is not available in this integration, so it unconditionally throws UnsupportedOperationException instead of delegating like the regular session methods do.

Solutions

  1. Do not use stateless session APIs: use the supported regular reactive session operations (persist, merge, remove via getSession) instead.
  2. If you need stateless-session semantics for bulk writes, use a panache/repository approach or plain Hibernate Reactive (SessionFactory#withStatelessSession) directly instead of this facade.
  3. Check the Quarkus version/changelog for when stateless support is added to this runtime, and upgrade if available.
  4. Refactor the calling code to replace getStatelessSession usage with Mutiny.Session obtained from getSession(entityClass).

Example fix

// before
Uni<Mutiny.StatelessSession> ss = ops.getStatelessSession(MyEntity.class);

// after
Uni<Mutiny.Session> session = ops.getSession(MyEntity.class);
return session.chain(s -> s.persist(new MyEntity()));
Defensive patterns

Strategy: type-guard

Validate before calling

// before calling the stateless API, verify the facade supports it
if (ops instanceof ManagedReactiveOperations mro) {
    // getStatelessSession is unsupported; route to getSession-based logic instead
}

Type guard

boolean supportsStateless(ManagedReactiveOperations ops) {
    return false; // this implementation never supports stateless sessions
}

Try / catch

try {
    return ops.getStatelessSession(entityClass);
} catch (UnsupportedOperationException e) {
    if (e.getMessage() != null && e.getMessage().equals("Stateless operations not supported")) {
        // fall back to session-based operations
        return ops.getSession(entityClass).map(s -> null); // adapt path
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getStatelessSession(...) on ManagedReactiveOperations — e.g. application or library code that uses the stateless-session API of the reactive Hibernate operations facade (a stateless insert/update/delete or bulk path) inside a Quarkus app using this extension.

Common situations: Migrating code written against plain Hibernate Reactive stateless sessions to Quarkus' data module; switching from a different persistence layer that supported stateless sessions; upgrading Quarkus and assuming stateless API parity.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at extensions/data/hibernate/runtime/src/main/java/io/quarkus/data/hibernate/runtime/hr/ManagedReactiveOperations.java:30

import io.quarkus.data.hibernate.runtime.spi.PanacheReactiveOperations;
import io.smallrye.mutiny.Uni;

public class ManagedReactiveOperations implements PanacheReactiveOperations {

    public final static ManagedReactiveOperations INSTANCE = new ManagedReactiveOperations();
    private final static ManagedReactiveJpaOperations DELEGATE = new ManagedReactiveJpaOperations();

    private ManagedReactiveOperations() {
    }

    @Override
    public Uni<Mutiny.Session> getSession(Class<?> entityClass) {
        return DELEGATE.getSession(entityClass);
    }

    @Override
    public Uni<Mutiny.StatelessSession> getStatelessSession(Class<?> entityClass) {
        throw new UnsupportedOperationException("Stateless operations not supported");
    }

    @Override
    public Uni<Void> insert(Object entity) {
        throw new UnsupportedOperationException("Stateless operations not supported");
    }

    @Override
    public Uni<Void> persist(Object entity) {
        return DELEGATE.persist(entity);
    }

    @Override
    public Uni<Void> persistAndFlush(Object entity) {
        return DELEGATE.persist(entity)
                .chain(v -> DELEGATE.flush(entity.getClass()));
    }

View on GitHub (pinned to e1c734241f)