quarkusio/quarkus · error · IllegalStateException

Booting a blocking Hibernate ORM serviceregistry on a Reacti

Error message

Booting a blocking Hibernate ORM serviceregistry on a Reactive RecordedState!

What it means

PreconfiguredServiceRegistryBuilder builds the blocking Hibernate ORM service registry from a RecordedState captured at augmentation time. checkIsNotReactive guards against misusing a RecordedState produced for Hibernate Reactive; booting the blocking registry with it would wire incompatible services, so it fails fast with this IllegalStateException.

Source

Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/boot/registry/PreconfiguredServiceRegistryBuilder.java:74

 * Helps to instantiate a ServiceRegistryBuilder from a previous state. This
 * will perform only minimal configuration validation and will never modify the
 * given configuration properties.
 * <p>
 * Meant to be used only to rebuild a previously created ServiceRegistry, which
 * has been created via the traditional methods, so this builder expects much
 * more explicit input.
 */
public class PreconfiguredServiceRegistryBuilder {

    private final Map<String, Object> configurationValues = new HashMap<>();
    private final List<StandardServiceInitiator<?>> initiators;
    private final List<ProvidedService<?>> providedServices = new ArrayList<ProvidedService<?>>();
    private final Collection<Integrator> integrators;
    private final StandardServiceRegistryImpl destroyedRegistry;

    private void checkIsNotReactive(RecordedState rs) {
        if (rs.isReactive())
            throw new IllegalStateException("Booting a blocking Hibernate ORM serviceregistry on a Reactive RecordedState!");
    }

    public PreconfiguredServiceRegistryBuilder(String puName, RecordedState rs,
            HibernateOrmRuntimeConfigPersistenceUnit puConfig) {
        checkIsNotReactive(rs);
        this.initiators = buildQuarkusServiceInitiatorList(puName, rs, puConfig);
        this.integrators = rs.getIntegrators();
        this.destroyedRegistry = (StandardServiceRegistryImpl) rs.getMetadata()
                .getMetadataBuildingOptions()
                .getServiceRegistry();
    }

    public PreconfiguredServiceRegistryBuilder applySetting(String settingName, Object value) {
        configurationValues.put(settingName, value);
        return this;
    }

    public PreconfiguredServiceRegistryBuilder addInitiator(StandardServiceInitiator<?> initiator) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Use the reactive bootstrap path (Reactive recorders / Hibernate Reactive registry builder) for reactive RecordedStates.
  2. Verify the persistence unit name passed to PreconfiguredServiceRegistryBuilder refers to a blocking PU, not the reactive one.
  3. Split the application into separate PUs: a blocking PU for ORM and a reactive PU for Hibernate Reactive, and boot each with its matching builder.

Example fix

// before
PreconfiguredServiceRegistryBuilder b = new PreconfiguredServiceRegistryBuilder("reactive-pu", reactiveRecordedState, puConfig);
// after
// boot the blocking PU instead, or use the reactive registry builder for reactive states
PreconfiguredServiceRegistryBuilder b = new PreconfiguredServiceRegistryBuilder("blocking-pu", blockingRecordedState, puConfig);
Defensive patterns

Strategy: type-guard

Validate before calling

// Before constructing the blocking registry builder
if (recordedState.isReactive()) {
    throw new IllegalStateException("Use the reactive registry builder for this RecordedState");
}

Type guard

boolean isBlockingRecordedState(RecordedState rs) {
    return rs != null && !rs.isReactive();
}

Try / catch

try {
    new PreconfiguredServiceRegistryBuilder(puName, rs, puConfig);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("Reactive RecordedState")) {
        log.error("PU " + puName + " is reactive; use the reactive bootstrap path");
    }
}

Prevention

When it happens

Trigger: Calling PreconfiguredServiceRegistryBuilder (or the code paths that construct it, e.g. static-init boot of a blocking EntityManagerFactory) with a RecordedState whose isReactive() returns true — i.e. the PU was recorded by the reactive extension.

Common situations: Mixing blocking Hibernate ORM boot code with a PU configured for Hibernate Reactive; extension/custom code selecting the wrong RecordedState by persistence unit name; an app adding blocking SessionFactory boot to a reactive Panache application.

Related errors


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