hibernate/hibernate-orm · critical · HibernateException

Multiple MutationExecutorService service registrations found

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.

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)

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.