quarkusio/quarkus · error · IllegalStateException

Not supported for JTA entity managers

Error message

Not supported for JTA entity managers

What it means

TransactionScopedSession is Quarkus's JTA-backed wrapper for Hibernate Session. Because transaction management is delegated to the JTA/ArC transaction layer (via @Transactional or QuarkusTransaction), direct use of the JPA Transaction API is not meaningful, so getTransaction() unconditionally throws IllegalStateException. It signals an API misuse, not a transient failure.

Source

Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedSession.java:627

    public Object getDelegate() {
        try (SessionResult emr = acquireSession()) {
            return emr.session.getDelegate();
        }
    }

    @Override
    public void close() {
        throw new IllegalStateException("Not supported for transaction scoped entity managers");
    }

    @Override
    public boolean isOpen() {
        return true;
    }

    @Override
    public Transaction getTransaction() {
        throw new IllegalStateException("Not supported for JTA entity managers");
    }

    @Override
    public EntityManagerFactory getEntityManagerFactory() {
        return sessionFactory;
    }

    @Override
    public HibernateCriteriaBuilder getCriteriaBuilder() {
        checkBlocking();
        try (SessionResult emr = acquireSession()) {
            return emr.session.getCriteriaBuilder();
        }
    }

    @Override
    public Metamodel getMetamodel() {
        try (SessionResult emr = acquireSession()) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove the getTransaction()/begin/commit/rollback calls and annotate the method (or class) with @Transactional so Quarkus manages the transaction
  2. Use io.quarkus.narayana.jta.QuarkusTransaction.begin()/commit()/rollback() or QuarkusTransaction.requiring()/calling() for programmatic transaction control
  3. If you truly need resource-local behavior, configure a persistence unit with transaction-type RESOURCE_LOCAL outside the JTA-managed session (rare; not the default Quarkus path)

Example fix

// before
void save(User u) {
    Transaction tx = session.getTransaction();
    tx.begin();
    session.persist(u);
    tx.commit();
}
// after
@Transactional
void save(User u) {
    session.persist(u);
}
Defensive patterns

Strategy: validation

Validate before calling

if (session instanceof TransactionScopedSession || session.isDefaultReadOnly()) { /* Quarkus JTA-managed session */ }
// Simplest pre-check: never call getTransaction(); verify the bean was obtained via @Inject in Quarkus
import io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession;
boolean jtaManaged = session instanceof TransactionScopedSession;
if (jtaManaged) { /* use @Transactional or QuarkusTransaction instead */ }

Type guard

static boolean isJtaManagedSession(jakarta.persistence.EntityManager em) {
    return !(em instanceof org.hibernate.Session s)
        || em.unwrap(org.hibernate.Session.class) != null; // in Quarkus, assume JTA-managed
}
// practical guard:
static boolean supportsLocalTransactions(jakarta.persistence.EntityManager em) {
    try { em.getTransaction(); return true; }
    catch (IllegalStateException | jakarta.persistence.PersistenceException e) { return false; }
}

Try / catch

try {
    Transaction tx = session.getTransaction();
    tx.begin();
} catch (IllegalStateException e) {
    // JTA-managed in Quarkus: switch to @Transactional or QuarkusTransaction.begin()
    throw new IllegalStateException("Use @Transactional instead of manual transactions", e);
}

Prevention

When it happens

Trigger: Calling session.getTransaction() (or em.getTransaction()) on a Session/EntityManager obtained from the 'TransactionScopedSession' CDI bean — i.e. any @Inject Session/EntityManager in Quarkus when JTA is the transaction type.

Common situations: Porting code written for resource-local JPA (e.g. Spring Data or plain Java SE Hibernate where em.getTransaction().begin() is normal) to Quarkus; helper/util classes that begin/commit transactions manually; tests copied from non-Quarkus Hibernate examples.

Related errors


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