hibernate/hibernate-orm · critical · HibernateException

Multiple MutationExecutorService service registrations…

Error message

Multiple MutationExecutorService service registrations found via ServiceLoader; specify one explicitly via 'hibernate.jdbc.mutation.executor'

What it means

When hibernate.jdbc.mutation.executor is not set, MutationExecutorServiceInitiator discovers implementations via Java's ServiceLoader (META-INF/services/org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService). If more than one implementation is discoverable on the classpath, Hibernate refuses to pick one arbitrarily and throws this HibernateException telling you to name the implementation explicitly.

Solutions

  1. Set hibernate.jdbc.mutation.executor to the fully-qualified class name of the implementation you want
  2. Or remove the duplicate registration: delete one of the META-INF/services entries / drop the redundant jar from the classpath
  3. In fat-jar/assembly builds, verify service files are merged rather than overwritten silently (use a ServiceResourceTransformer)

Example fix

# before (ambiguous discovery)
# (no property set; two jars provide implementations)

# after
hibernate.jdbc.mutation.executor=com.example.MyMutationExecutorService
Defensive patterns

Strategy: validation

Validate before calling

// detect ambiguous service registrations before boot
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Enumeration<URL> urls = cl.getResources("META-INF/services/org.hibernate.engine.jdbc.mutation.spi.MutationExecutorService");
if (Collections.list(urls).size() > 1) {
    // set hibernate.jdbc.mutation.executor explicitly or drop a jar
}

Prevention

When it happens

Trigger: Two or more jars on the classpath each register a MutationExecutorService in their META-INF/services file — for example two internal platform libraries, or a library plus your own custom executor — while hibernate.jdbc.mutation.executor is unset.

Common situations: Shared platform/library jars that ship alternative mutation executors (e.g. batching or telemetry variants); fat jars merging service files; adding a second custom-executor jar without configuring the property.

Related errors


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

Appendix: source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/mutation/internal/MutationExecutorServiceInitiator.java:83

			catch (NoSuchMethodException e) {
				throw new HibernateException(
						"Could not locate appropriate MutationExecutorService constructor : " + customImplClass.getName(),
						e );
			}
			catch (Exception e) {
				throw new HibernateException(
						"Unable to instantiate custom MutationExecutorService : " + customImplClass.getName(), e );
			}
		}
	}

	private static MutationExecutorService discover(ClassLoaderService classLoaderService) {
		final var discovered = classLoaderService.loadJavaServices( MutationExecutorService.class );
		final var iterator = discovered.iterator();
		if ( iterator.hasNext() ) {
			final var selected = iterator.next();
			if ( iterator.hasNext() ) {
				throw new HibernateException(
						"Multiple MutationExecutorService service registrations found via ServiceLoader; "
						+ "specify one explicitly via '" + EXECUTOR_KEY + "'" );
			}
			return selected;
		}
		else {
			return null;
		}
	}

	private MutationExecutorService createStandardService(Map<String, Object> configurationValues) {
		return new StandardMutationExecutorService( configurationValues );
	}
}

View on GitHub (pinned to fad1729dce)