hibernate/hibernate-orm · error · IllegalArgumentException

ServiceRegistry parent needs to implement ServiceRegistryImp

Error message

ServiceRegistry parent needs to implement ServiceRegistryImplementor

What it means

AbstractServiceRegistryImpl's constructor requires the supplied BootstrapServiceRegistry to also implement the internal SPI interface ServiceRegistryImplementor. Any custom BootstrapServiceRegistry implementation (or test mock) that only implements the public interface fails fast with IllegalArgumentException — Hibernate cannot manage parent/child registry links through an unknown implementation.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/service/internal/AbstractServiceRegistryImpl.java:95

	protected AbstractServiceRegistryImpl(
			@Nullable ServiceRegistryImplementor parent,
			boolean autoCloseRegistry) {

		this.parent = parent;
		this.allowCrawling = getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
		this.autoCloseRegistry = autoCloseRegistry;
	}

	public AbstractServiceRegistryImpl(BootstrapServiceRegistry bootstrapServiceRegistry) {
		this( bootstrapServiceRegistry, true );
	}

	public AbstractServiceRegistryImpl(
			BootstrapServiceRegistry bootstrapServiceRegistry,
			boolean autoCloseRegistry) {
		this.autoCloseRegistry = autoCloseRegistry;
		if ( !(bootstrapServiceRegistry instanceof ServiceRegistryImplementor) ) {
			throw new IllegalArgumentException( "ServiceRegistry parent needs to implement ServiceRegistryImplementor" );
		}
		this.parent = (ServiceRegistryImplementor) bootstrapServiceRegistry;
		this.allowCrawling = getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
	}

	// For nullness checking purposes
	protected void initialize() {
		if ( parent != null ) {
			parent.registerChild( this );
		}
	}

	protected <R extends Service> void createServiceBinding(ServiceInitiator<R> initiator) {
		serviceBindingMap.put( initiator.getServiceInitiated(),
				new ServiceBinding<>( this, initiator ) );
	}

	protected <R extends Service> void createServiceBinding(ProvidedService<R> providedService) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Obtain the bootstrap registry from BootstrapServiceRegistryBuilder.build() instead of implementing the interface yourself
  2. If you must customize it, extend Hibernate's own bootstrap registry implementation rather than re-implementing the interface
  3. In tests, make any mock implement ServiceRegistryImplementor or just use a real builder-built registry

Example fix

// before
BootstrapServiceRegistry custom = new MyBootstrapRegistry(); // only implements BootstrapServiceRegistry
new StandardServiceRegistryImpl(custom, true); // IllegalArgumentException

// after
BootstrapServiceRegistry bootstrap = new BootstrapServiceRegistryBuilder().build();
StandardServiceRegistry registry = new StandardServiceRegistryBuilder(bootstrap).build();
Defensive patterns

Strategy: type-guard

Validate before calling

if (bootstrapServiceRegistry == null
        || !(bootstrapServiceRegistry instanceof ServiceRegistryImplementor)) {
    bootstrapServiceRegistry = new BootstrapServiceRegistryBuilder().build();
}

Type guard

boolean isValidBootstrapParent(BootstrapServiceRegistry bsr) {
    return bsr instanceof ServiceRegistryImplementor;
}

Prevention

When it happens

Trigger: Constructing a StandardServiceRegistryImpl (or any AbstractServiceRegistryImpl subclass) with a hand-written BootstrapServiceRegistry; passing a Mockito mock of BootstrapServiceRegistry in unit tests; wrapping the bootstrap registry in a delegating facade.

Common situations: Custom bootstrap plumbing in application servers or test harnesses; migration code that wraps registries; tests that try to stub registry behavior instead of using the builders.

Related errors


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