hibernate/hibernate-orm · error · ServiceException

Could not initialize custom PersisterClassResolver impl [%s]

Error message

Could not initialize custom PersisterClassResolver impl [%s]

What it means

PersisterClassResolverInitiator loads the class configured under the hibernate.persister.resolver setting (AvailableSettings.PERSISTER_CLASS_RESOLVER) and instantiates it with newInstance(). Any construction failure - no public no-arg constructor, abstract class, or a constructor/static initializer that throws - is wrapped in a ServiceException naming the class. SessionFactory bootstrap fails immediately.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java:50

		if ( customImpl == null ) {
			return new StandardPersisterClassResolver();
		}

		if ( customImpl instanceof PersisterClassResolver persisterClassResolver ) {
			return persisterClassResolver;
		}

		@SuppressWarnings("unchecked")
		final var customImplClass =
				customImpl instanceof Class
						? (Class<? extends PersisterClassResolver>) customImpl
						: locate( registry, customImpl.toString() );

		try {
			return customImplClass.newInstance();
		}
		catch (Exception e) {
			throw new ServiceException( "Could not initialize custom PersisterClassResolver impl [" + customImplClass.getName() + "]", e );
		}
	}

	private Class<? extends PersisterClassResolver> locate(ServiceRegistryImplementor registry, String className) {
		return registry.requireService( ClassLoaderService.class ).classForName( className );
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Give the resolver a public no-arg constructor that cannot throw (do heavy setup lazily)
  2. Confirm the class implements PersisterClassResolver and is on the runtime classpath visible to Hibernate's classloader
  3. Verify the setting value: fully-qualified name, no typos, in every active config source
  4. Inspect the ServiceException's cause chain for the real construction error (e.g. static init failing on missing config)

Example fix

// before: resolver with no usable constructor
public class ReadOnlyResolver implements PersisterClassResolver {
    ReadOnlyResolver(DataSource ds) { ... } // no no-arg ctor -> newInstance() fails
}

// after: public no-arg constructor, heavy wiring deferred
public class ReadOnlyResolver implements PersisterClassResolver {
    public ReadOnlyResolver() { }
    // lazily initialized internals
}
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast before boot: the configured resolver must be instantiable
String cn = cfg.getProperty("hibernate.persister.resolver");
if (cn != null) {
    Class<?> c = Class.forName(cn);
    if (!PersisterClassResolver.class.isAssignableFrom(c) || c.getDeclaredConstructor() == null) {
        throw new IllegalStateException("Invalid PersisterClassResolver: " + cn);
    }
    c.getDeclaredConstructor().newInstance(); // dry-run construction
}

Try / catch

try {
    sessionFactory = cfg.buildSessionFactory();
} catch (ServiceException e) {
    if (e.getMessage() != null && e.getMessage().contains("PersisterClassResolver")) {
        // fix the hibernate.persister.resolver config (public no-arg ctor, on classpath)
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting hibernate.persister.resolver to a class without a public no-arg constructor; a resolver whose constructor or static initializer throws (missing config, NPE during init); a stale or misspelled class name in persistence.xml, hibernate.cfg.xml, or spring.jpa.properties; class not visible to Hibernate's ClassLoaderService after shading/repackaging.

Common situations: Custom persisters used for read-only or specialized tables; refactors that renamed the resolver while configuration kept the old FQCN; fat-jar or OSGi classloading issues; Spring Boot property files carrying a stale class reference.

Related errors


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