hibernate/hibernate-orm · error · IllegalStateException

Should not register strategies during shutdown

Error message

Should not register strategies during shutdown

What it means

Once shutdown begins, StrategySelectorImpl swaps its contribution handler to ShutdownContributions, whose contributeStrategyImplementor() throws IllegalStateException - registering new strategies into a registry being torn down would corrupt the shutdown sequence. The remove path still works; only new contributions are rejected.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorImpl.java:279

		}
	}

	private class StartupContributions implements NamedStrategyContributions {
		@Override
		public <T> void contributeStrategyImplementor(Class<T> strategy, Class<? extends T> implementation, String... names) {
			contributeImplementation( strategy, implementation, names );
		}

		@Override
		public <T> void removeStrategyImplementor(Class<T> strategy, Class<? extends T> implementation) {
			removeImplementation( strategy, implementation );
		}
	}

	private class ShutdownContributions extends StartupContributions {
		@Override
		public <T> void contributeStrategyImplementor(Class<T> strategy, Class<? extends T> implementation, String... names) {
			throw new IllegalStateException( "Should not register strategies during shutdown" );
		}
	}

	@Override @Deprecated(forRemoval = true)
	public <T> void registerStrategyImplementor(Class<T> strategy, String name, Class<? extends T> implementation) {
		contributeImplementation( strategy, implementation, name );
	}

	@Override @Deprecated(forRemoval = true)
	public <T> void unRegisterStrategyImplementor(Class<T> strategy, Class<? extends T> implementation) {
		removeImplementation( strategy, implementation );
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Guard every dynamic registration with a check that the owning registry is still active before contributing
  2. Ensure strategy registration completes fully during startup, not from shutdown hooks or listeners
  3. Cancel or join registration threads before closing the SessionFactory/registry

Example fix

// before
Runtime.getRuntime().addShutdownHook(new Thread(() ->
    strategySelector.addStrategyImplementor(Dialect.class, MyDialect.class, "mine"))); // during shutdown -> throws

// after
strategySelector.addStrategyImplementor(Dialect.class, MyDialect.class, "mine"); // register at startup
Defensive patterns

Strategy: validation

Validate before calling

// Guard every dynamic registration against registry liveness
if (!serviceRegistry.isActive()) {
    log.debug("Registry shutting down - skipping strategy registration for {}", strategy);
    return;
}
strategySelector.addStrategyImplementor(strategy, implementation, names);

Try / catch

try {
    strategySelector.addStrategyImplementor(strategy, implementation, names);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("during shutdown")) {
        // registration raced with shutdown: drop it; the registry is going away anyway
        return;
    }
    throw e;
}

Prevention

When it happens

Trigger: Any code registering a strategy (addStrategyImplementor or the deprecated registerStrategyImplementor) that executes during or after registry destroy - e.g., a shutdown hook, an integration reacting to shutdown events, or a race between application shutdown and dynamic registration.

Common situations: Integrations that lazily register strategies on first use and get touched during shutdown; background threads still registering while the SessionFactory closes; custom lifecycle code mixing registration with teardown.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/a4871b027dbb10df. Report an issue: GitHub.