{"record":{"id":"8eeb90ed8fe0d619","repo":"hibernate/hibernate-orm","slug":"multiple-statisticsfactory-service-registrations-f","errorCode":null,"errorMessage":"Multiple StatisticsFactory service registrations found via ServiceLoader; specify one explicitly via 'hibernate.stats.factory'","messagePattern":"Multiple StatisticsFactory service registrations found via ServiceLoader; specify one explicitly via 'hibernate\\.stats\\.factory'","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsInitiator.java","lineNumber":88,"sourceCode":"\t\t\tcatch (HibernateException e) {\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t\tcatch (Exception e) {\n\t\t\t\tthrow new HibernateException(\n\t\t\t\t\t\t\"Unable to instantiate specified StatisticsFactory implementation [\" + configValue + \"]\",\n\t\t\t\t\t\te\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static @Nullable StatisticsFactory discover(@Nonnull ClassLoaderService classLoaderService) {\n\t\tfinal var discovered = classLoaderService.loadJavaServices( StatisticsFactory.class );\n\t\tfinal var iterator = discovered.iterator();\n\t\tif ( iterator.hasNext() ) {\n\t\t\tfinal var selected = iterator.next();\n\t\t\tif ( iterator.hasNext() ) {\n\t\t\t\tthrow new HibernateException(\n\t\t\t\t\t\t\"Multiple StatisticsFactory service registrations found via ServiceLoader; \"\n\t\t\t\t\t\t+ \"specify one explicitly via '\" + STATS_BUILDER + \"'\" );\n\t\t\t}\n\t\t\treturn selected;\n\t\t}\n\t\telse {\n\t\t\treturn null;\n\t\t}\n\t}\n}\n","sourceCodeStart":70,"sourceCodeEnd":99,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsInitiator.java#L70-L99","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\n# two jars each provide META-INF/services/org.hibernate.stat.spi.StatisticsFactory -> boot fails\n\n# after\n<property name=\"hibernate.stats.factory\" value=\"org.acme.MetricsStatisticsFactory\"/>","handlingStrategy":"try-catch","validationCode":"long providers = java.util.ServiceLoader\n        .load(org.hibernate.stat.spi.StatisticsFactory.class,\n              Thread.currentThread().getContextClassLoader())\n        .stream().count();\nif (providers > 1) {\n    props.put(\"hibernate.stats.factory\", \"org.acme.MetricsStatisticsFactory\"); // disambiguate before boot\n}","typeGuard":null,"tryCatchPattern":"try {\n    sessionFactory = cfg.buildSessionFactory();\n} catch (HibernateException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Multiple StatisticsFactory\")) {\n        // set hibernate.stats.factory explicitly and rebuild\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["hibernate","statistics","serviceloader","classpath","configuration"],"backgroundTag":"conflicting-service-registrations","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}