hibernate/hibernate-orm · error · IllegalStateException
BootstrapContext is no longer available
Error message
BootstrapContext is no longer available
What it means
Hibernate hands each Integrator an Integrator.Context; on this implementation getBootstrapContext() deliberately throws IllegalStateException because the BootstrapContext (bootstrap-time services, classmate access, managed beans) is discarded once the SessionFactory is built. The context exposed by IntegratorObserver is only intended for disintegrate() callbacks at factory close. Any integrator that asks for the BootstrapContext after bootstrap will always get this error.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java:545
}
@Override
@Nonnull
public PlanningOptions getGraphPlanningOptions() {
return graphPlanningOptions;
}
@SuppressWarnings("removal")
class IntegratorObserver implements SessionFactoryObserver {
private final Integrator.Context context = new Integrator.Context() {
@Override
public ManagedBeanRegistry getManagedBeanRegistry() {
return SessionFactoryImpl.this.getManagedBeanRegistry();
}
@Override
public BootstrapContext getBootstrapContext() {
throw new IllegalStateException( "BootstrapContext is no longer available" );
}
};
private final ArrayList<Integrator> integrators = new ArrayList<>();
@Override
public void sessionFactoryClosed(SessionFactory factory) {
for ( var integrator : integrators ) {
integrator.disintegrate( SessionFactoryImpl.this, context );
}
integrators.clear();
}
}
@SuppressWarnings("removal")
private static Integrator.Context createIntegratorContext(BootstrapContext bootstrapContext) {
return () -> bootstrapContext;
}
View on GitHub (pinned to fad1729dce)
Solutions
- Cache everything you need from BootstrapContext (ServiceRegistry, ManagedBeanRegistry, BeanContainer) in fields during integrate(); never call context.getBootstrapContext() in disintegrate()
- If you need managed beans at shutdown, use context.getManagedBeanRegistry() which is still supported on this Context implementation
- Upgrade the integrator library to a Hibernate 6.2+/7.x compatible build where the new Integrator.Context contract is respected
- If you control the code, restructure the integrator so shutdown work only needs the SessionFactoryImplementor passed to disintegrate()
Example fix
// before
@Override
public void disintegrate(SessionFactoryImplementor factory, Integrator.Context context) {
context.getBootstrapContext().getServiceRegistry(); // IllegalStateException
}
// after
private ServiceRegistry serviceRegistry;
@Override
public void integrate(Metadata metadata, BootstrapContext bootstrapContext,
SessionFactoryImplementor sessionFactory) {
this.serviceRegistry = bootstrapContext.getServiceRegistry(); // capture at bootstrap
}
@Override
public void disintegrate(SessionFactoryImplementor factory, Integrator.Context context) {
// use the cached serviceRegistry; never call context.getBootstrapContext()
} Defensive patterns
Strategy: validation
Validate before calling
// In your integrator, gate on a flag you control instead of probing the context
private boolean bootstrapped;
@Override
public void integrate(Metadata md, BootstrapContext ctx, SessionFactoryImplementor sf) {
this.captured = ctx.getServiceRegistry();
this.bootstrapped = true;
}
@Override
public void disintegrate(SessionFactoryImplementor sf, Integrator.Context ctx) {
if (!bootstrapped) return; // integrate never ran; do not touch bootstrap resources
// use `captured`, never ctx.getBootstrapContext()
} Try / catch
try {
// integrator shutdown logic
} catch (IllegalStateException e) {
// BootstrapContext is gone after bootstrap; fall back to data cached at integrate()
LOG.warn("bootstrap context unavailable at disintegrate; using cached state", e);
} Prevention
- Treat BootstrapContext as bootstrap-only: snapshot everything you need in integrate() and never store the context itself
- Use Integrator.Context.getManagedBeanRegistry() for bean lookups at disintegrate() — it stays available
- When upgrading Hibernate major versions, re-read the org.hibernate.integrator.spi.Integrator contract — signature and lifecycle guarantees change
- Add an integration test that builds and closes a SessionFactory with your integrator to catch lifecycle regressions early
When it happens
Trigger: An org.hibernate.integrator.spi.Integrator implementation calls context.getBootstrapContext() inside disintegrate(sessionFactory, context), or stores the Integrator.Context and calls getBootstrapContext() after SessionFactoryObserver.sessionFactoryClosed fires. Also hit by integrators ported from older Hibernate versions where disintegrate() used to receive a BootstrapContext parameter.
Common situations: Upgrading a custom integrator from Hibernate 5.x/6.0 to 6.2+/7.x where the disintegrate signature changed to Integrator.Context; third-party integrator libraries (auditing, multi-tenancy, metrics) that still touch bootstrap services at shutdown; integrators that resolve beans via BootstrapContext instead of caching them during integrate().
Related errors
- The ClassLoaderService cannot be reused (this instance was s
- No child ServiceRegistry registrations found
- Should not register strategies during shutdown
- Duplicate event listener found
- EntityManagerFactory is already closed
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/59238b247913a30b.
Report an issue: GitHub.