quarkusio/quarkus · error · IllegalStateException

Attempting to boot a blocking Hibernate ORM instance on a re

Error message

Attempting to boot a blocking Hibernate ORM instance on a reactive RecordedState

What it means

Blocking Hibernate ORM and Hibernate Reactive produce different build-time RecordedState objects. When a persistence unit was built as reactive but is booted through the blocking FastBootHibernatePersistenceProvider, getEntityManagerFactoryBuilderOrNull throws IllegalStateException because a reactive RecordedState cannot construct a blocking EntityManagerFactory.

Source

Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/FastBootHibernatePersistenceProvider.java:205

                    persistenceUnit.getName(), persistenceUnit.getProviderClassName(), persistenceUnitName);

            final boolean matches = persistenceUnitName == null
                    || persistenceUnit.getName().equals(persistenceUnitName);
            if (!matches) {
                log.debugf("Excluding from consideration '%s' due to name mismatch", persistenceUnit.getName());
                continue;
            }

            // See if we (Hibernate) are the persistence provider
            if (!isProvider(persistenceUnit)) {
                log.debug("Excluding from consideration due to provider mismatch");
                continue;
            }

            RecordedState recordedState = PersistenceUnitsHolder.popRecordedState(persistenceUnitName, false);

            if (recordedState.isReactive()) {
                throw new IllegalStateException(
                        "Attempting to boot a blocking Hibernate ORM instance on a reactive RecordedState");
            }
            final PrevalidatedQuarkusMetadata metadata = recordedState.getMetadata();
            var puConfig = hibernateOrmRuntimeConfig.persistenceUnits().get(persistenceUnit.getName());
            if (puConfig.active().isPresent() && !puConfig.active().get()) {
                throw new IllegalStateException(
                        "Attempting to boot a deactivated Hibernate ORM persistence unit");
            }
            RuntimeSettingsResult runtimeSettingsResult = buildRuntimeSettings(persistenceUnitName, recordedState,
                    puConfig);

            StandardServiceRegistry standardServiceRegistry = rewireMetadataAndExtractServiceRegistry(persistenceUnitName,
                    recordedState, puConfig, runtimeSettingsResult.settings());

            final Object cdiBeanManager = Arc.container().beanManager();
            final Object validatorFactory = Arc.container().instance("quarkus-hibernate-validator-factory").get();

            return new FastBootEntityManagerFactoryBuilder(

View on GitHub (pinned to e1c734241f)

Solutions

  1. Use Hibernate Reactive APIs (MutinySessionFactory) for reactive persistence units.
  2. Remove quarkus.hibernate-reactive.* config if the PU should be blocking and configure via quarkus.hibernate-orm.*.
  3. Split into separate PUs: reactive PUs for reactive code, blocking PUs for blocking code.
  4. Match the Panache variant (hibernate-reactive-panache vs hibernate-orm-panache) to your access pattern.

Example fix

// before (PU configured reactive, blocking bootstrap)
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mypu");
// after
@Inject
MutinySessionFactory sessionFactory;
Defensive patterns

Strategy: validation

Validate before calling

if (puUsesHibernateReactive("mypu") && needsBlockingEntityManagerFactory) {
    throw new IllegalStateException("mypu is reactive; use MutinySessionFactory instead");
}

Try / catch

try {
    Persistence.createEntityManagerFactory("mypu");
} catch (IllegalStateException e) {
    if (e.getMessage().contains("reactive RecordedState")) {
        throw new IllegalStateException("Use Hibernate Reactive APIs for this PU", e);
    } else throw e;
}

Prevention

When it happens

Trigger: getEntityManagerFactoryBuilderOrNull pops the RecordedState via PersistenceUnitsHolder.popRecordedState and recordedState.isReactive() is true on the blocking provider path; reached via builder or getEntityManagerFactoryBuilder.

Common situations: hibernate-reactive configuration (quarkus.hibernate-reactive.*) on a PU then accessed with blocking bootstrap APIs; mixing blocking Panache with a reactive PU; copied blocking bootstrap code into a reactive project.

Related errors


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