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
- Set hibernate.jdbc.mutation.executor to the fully-qualified class name of the implementation you want
- Or remove the duplicate registration: delete one of the META-INF/services entries / drop the redundant jar from the classpath
- 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
- Set hibernate.jdbc.mutation.executor whenever multiple provider jars exist
- Use ServiceResourceTransformer in fat-jar builds
- Review new dependencies for Hibernate SPI registrations
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
- Unable to build configuration.xml JAXBContext
- Unable to load class [" + className + "]
- Unknown TcclLookupPrecedence - {}
- Implementation class [{}] does not implement strategy interf
- Default resolver threw exception
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3c330f78cdb37316.
Report an issue: GitHub.