hibernate/hibernate-orm · error · HibernateException

Unable to instantiate specified StatisticsFactory implementa

Error message

Unable to instantiate specified StatisticsFactory implementation [{}]

What it means

When hibernate.stats.factory names a class, StatisticsInitiator loads it through ClassLoaderService and instantiates it reflectively (Class#newInstance()). Any load or construction failure — class missing from the classpath, no accessible no-arg constructor, abstract/interface class, or a constructor that throws — is wrapped in a HibernateException with this message (a HibernateException raised during the lookup itself is rethrown unchanged, so read the chained cause).

Source

Thrown at hibernate-core/src/main/java/org/hibernate/stat/internal/StatisticsInitiator.java:74

		if ( configValue == null ) {
			final var discovered = discover( classLoaderService );
			return discovered != null ? discovered : StatisticsImpl::new;
		}
		else if ( configValue instanceof StatisticsFactory factory ) {
			return factory;
		}
		else {
			// assume it names the factory class
			try {
				return (StatisticsFactory)
						classLoaderService.classForName( configValue.toString() )
								.newInstance();
			}
			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;

View on GitHub (pinned to fad1729dce)

Solutions

  1. Give the class a public no-arg constructor and make sure it implements org.hibernate.stat.spi.StatisticsFactory.
  2. Fix the class name/deployment so the class is visible to Hibernate's ClassLoaderService (check shaded-jar relocations, missing dependency, app-server module visibility).
  3. Read the chained cause via getCause() on the HibernateException and fix the underlying failure (missing constructor dependency, config the constructor reads).

Example fix

// before
public class MetricsStatisticsFactory implements StatisticsFactory {
    MetricsStatisticsFactory(MeterRegistry registry) { ... } // no no-arg ctor -> instantiation fails
}

// after
public class MetricsStatisticsFactory implements StatisticsFactory {
    public MetricsStatisticsFactory() { ... } // resolve the registry lazily on first use
}
Defensive patterns

Strategy: try-catch

Validate before calling

Class<?> clazz = Class.forName(factoryClassName, false, Thread.currentThread().getContextClassLoader());
if (!org.hibernate.stat.spi.StatisticsFactory.class.isAssignableFrom(clazz)
        || clazz.getConstructor() == null) {
    throw new IllegalStateException("hibernate.stats.factory class must implement StatisticsFactory with a no-arg ctor");
}

Type guard

static boolean usableStatisticsFactory(Class<?> c) {
    return org.hibernate.stat.spi.StatisticsFactory.class.isAssignableFrom(c)
            && java.lang.reflect.Modifier.isPublic(c.getModifiers())
            && !java.lang.reflect.Modifier.isAbstract(c.getModifiers());
}

Try / catch

try {
    sessionFactory = cfg.buildSessionFactory();
} catch (HibernateException e) {
    if (e.getMessage() != null && e.getMessage().contains("StatisticsFactory")) {
        // read e.getCause(): missing class, bad ctor, or ctor failure
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting hibernate.stats.factory=org.acme.MetricsStatisticsFactory where the class is not on the runtime classpath, is package-private, lacks a public no-arg constructor, or whose constructor throws (for example it eagerly contacts a metrics registry that is not available at bootstrap).

Common situations: Custom StatisticsFactory integrations for Micrometer/Prometheus; fat-jar or application-server module classpath differences between dev and prod; constructors that do eager external work at boot; class renamed or relocated by a shading plugin.

Related errors


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