hibernate/hibernate-orm · error · HibernateException
Multiple StatisticsFactory service registrations found via S
Error message
Multiple StatisticsFactory service registrations found via ServiceLoader; specify one explicitly via 'hibernate.stats.factory'
What it means
When hibernate.stats.factory is not set, StatisticsInitiator discovers StatisticsFactory implementations via java.util.ServiceLoader (META-INF/services/org.hibernate.stat.spi.StatisticsFactory). Finding more than one registration is ambiguous — Hibernate cannot choose which factory builds Statistics — so bootstrap fails with this HibernateException rather than guessing.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsInitiator.java:88
catch (HibernateException e) {
throw e;
}
catch (Exception e) {
throw new HibernateException(
"Unable to instantiate specified StatisticsFactory implementation [" + configValue + "]",
e
);
}
}
}
private static @Nullable StatisticsFactory discover(@Nonnull ClassLoaderService classLoaderService) {
final var discovered = classLoaderService.loadJavaServices( StatisticsFactory.class );
final var iterator = discovered.iterator();
if ( iterator.hasNext() ) {
final var selected = iterator.next();
if ( iterator.hasNext() ) {
throw new HibernateException(
"Multiple StatisticsFactory service registrations found via ServiceLoader; "
+ "specify one explicitly via '" + STATS_BUILDER + "'" );
}
return selected;
}
else {
return null;
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Set hibernate.stats.factory explicitly to the implementation you want — an explicit setting bypasses ServiceLoader discovery entirely.
- Remove the redundant provider: exclude the duplicate dependency, or strip one META-INF/services/org.hibernate.stat.spi.StatisticsFactory entry from your packaging.
Example fix
# before # two jars each provide META-INF/services/org.hibernate.stat.spi.StatisticsFactory -> boot fails # after <property name="hibernate.stats.factory" value="org.acme.MetricsStatisticsFactory"/>
Defensive patterns
Strategy: try-catch
Validate before calling
long providers = java.util.ServiceLoader
.load(org.hibernate.stat.spi.StatisticsFactory.class,
Thread.currentThread().getContextClassLoader())
.stream().count();
if (providers > 1) {
props.put("hibernate.stats.factory", "org.acme.MetricsStatisticsFactory"); // disambiguate before boot
} Try / catch
try {
sessionFactory = cfg.buildSessionFactory();
} catch (HibernateException e) {
if (e.getMessage() != null && e.getMessage().contains("Multiple StatisticsFactory")) {
// set hibernate.stats.factory explicitly and rebuild
}
throw e;
} Prevention
- Run dependency:tree checks that flag duplicate META-INF/services providers for StatisticsFactory.
- Always set hibernate.stats.factory explicitly in environments where multiple integrations coexist.
- Audit classpath after adding a monitoring/telemetry jar.
When it happens
Trigger: Two jars on the classpath each shipping a META-INF/services/org.hibernate.stat.spi.StatisticsFactory entry: the discover() helper loads all registrations, sees a second one after the first, and throws during SessionFactory startup.
Common situations: Adding a telemetry/monitoring jar that also registers a StatisticsFactory while another integration is already present; duplicate versions of the same integration jar after a dependency merge; transitive dependencies silently pulling a second provider.
Related errors
- Multiple active MetadataBuilder definitions were discovered
- Unable to build configuration.xml JAXBContext
- Unable to load class [" + className + "]
- Multiple MutationExecutorService service registrations found
- Unknown cache region : {}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/8eeb90ed8fe0d619.
Report an issue: GitHub.