hibernate/hibernate-orm · critical · ServiceException

Multiple BeanContainer service implementations found (set…

Error message

Multiple BeanContainer service implementations found (set 'hibernate.resource.beans.container' explicitly)

What it means

ManagedBeanRegistryInitiator discovers BeanContainer implementations through the Java ServiceLoader (META-INF/services/org.hibernate.resource.beans.spi.BeanContainer) and requires exactly one when 'hibernate.resource.beans.container' is unset. Finding more than one is ambiguous, so bootstrap fails with ServiceException('Multiple BeanContainer service implementations found (set hibernate.resource.beans.container explicitly)').

Solutions

  1. Set the property explicitly to one implementation: props.put("hibernate.resource.beans.container", "org.hibernate.resource.beans.container.internal.CdiBeanContainerImpl").
  2. Find and exclude the duplicate integration dependency from the classpath (check the dependency tree).
  3. Inspect the merged META-INF/services/org.hibernate.resource.beans.spi.BeanContainer file in fat jars and keep a single line.
  4. Verify with ServiceLoader.load(BeanContainer.class) in a startup self-check that exactly one provider resolves.

Example fix

// before
// classpath contains both weld-hibernate-integration.jar and appserver-integration.jar,
// each registering META-INF/services/...BeanContainer -> ServiceException at boot

// after
Map<String, Object> props = new HashMap<>();
props.put("hibernate.resource.beans.container",
    "org.hibernate.resource.beans.container.internal.CdiBeanContainerImpl");
EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu", props);
Defensive patterns

Strategy: validation

Validate before calling

// startup self-check: exactly one BeanContainer provider on the classpath
List<BeanContainer> providers = new ArrayList<>();
for (BeanContainer bc : ServiceLoader.load(BeanContainer.class, Thread.currentThread().getContextClassLoader())) {
    providers.add(bc);
}
if (providers.size() > 1) {
    props.put("hibernate.resource.beans.container", chosenProvider.getClass().getName());
}

Try / catch

try {
    emf = Persistence.createEntityManagerFactory("pu", props);
} catch (org.hibernate.service.spi.ServiceException e) {
    if (e.getMessage().contains("Multiple BeanContainer")) {
        // set hibernate.resource.beans.container explicitly or drop the duplicate integration jar
        throw new ConfigurationException(e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: The runtime classpath carries two or more BeanContainer service registrations: e.g. a Weld/Omnifaces-style CDI integration plus a platform-specific one (Quarkus, app server), or two copies of an integration jar.

Common situations: Fat/shaded jars that merge multiple META-INF/services files; mixing app-server integration fragments into a SE app; dependency upgrades pulling in an extra Hibernate-CDI integration transitively.

Related errors


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

Appendix: source

Thrown at hibernate-core/src/main/java/org/hibernate/resource/beans/spi/ManagedBeanRegistryInitiator.java:69

		return new ManagedBeanRegistryImpl( resolveBeanContainer( configurationValues, serviceRegistry ) );
	}

	private BeanContainer resolveBeanContainer(Map<?,?> configurationValues, ServiceRegistry serviceRegistry) {
		// was a specific container explicitly specified?
		final Object explicitBeanContainer = configurationValues.get( BEAN_CONTAINER );
		return explicitBeanContainer == null
				? interpretImplicitBeanContainer( serviceRegistry )
				: interpretExplicitBeanContainer( explicitBeanContainer, serviceRegistry );
	}

	private static BeanContainer interpretImplicitBeanContainer(ServiceRegistry serviceRegistry) {
		final Collection<BeanContainer> beanContainers =
				serviceRegistry.requireService( ClassLoaderService.class )
						.loadJavaServices( BeanContainer.class );
		return switch ( beanContainers.size() ) {
			case 1 -> beanContainers.iterator().next();
			case 0 -> interpretImplicitCdiBeanContainer( serviceRegistry );
			default -> throw new ServiceException( "Multiple BeanContainer service implementations found"
													+ " (set '" + BEAN_CONTAINER + "' explicitly)" );
		};
	}

	// simplified CDI support
	private static BeanContainer interpretImplicitCdiBeanContainer(ServiceRegistry serviceRegistry) {
		final Object beanManager = getConfiguredBeanManager( serviceRegistry );
		final boolean isCdiAvailable = isCdiAvailable( serviceRegistry );
		if ( beanManager != null ) {
			if ( !isCdiAvailable ) {
				throw new ServiceException( "A bean manager was provided via '" + JAKARTA_CDI_BEAN_MANAGER
											+ "' but CDI is not available on the Hibernate class loader");
			}
			return CdiBeanContainerBuilder.fromBeanManagerReference( beanManager, serviceRegistry );
		}
		else {
			if ( isCdiAvailable ) {
				BEANS_MSG_LOGGER.noBeanManagerButCdiAvailable();

View on GitHub (pinned to fad1729dce)