{"record":{"id":"0746a714f7595b01","repo":"hibernate/hibernate-orm","slug":"could-not-initialize-custom-persisterclassresolver","errorCode":null,"errorMessage":"Could not initialize custom PersisterClassResolver impl [%s]","messagePattern":"Could not initialize custom PersisterClassResolver impl \\[(.+?)\\]","errorType":"exception","errorClass":"ServiceException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java","lineNumber":50,"sourceCode":"\t\tif ( customImpl == null ) {\n\t\t\treturn new StandardPersisterClassResolver();\n\t\t}\n\n\t\tif ( customImpl instanceof PersisterClassResolver persisterClassResolver ) {\n\t\t\treturn persisterClassResolver;\n\t\t}\n\n\t\t@SuppressWarnings(\"unchecked\")\n\t\tfinal var customImplClass =\n\t\t\t\tcustomImpl instanceof Class\n\t\t\t\t\t\t? (Class<? extends PersisterClassResolver>) customImpl\n\t\t\t\t\t\t: locate( registry, customImpl.toString() );\n\n\t\ttry {\n\t\t\treturn customImplClass.newInstance();\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new ServiceException( \"Could not initialize custom PersisterClassResolver impl [\" + customImplClass.getName() + \"]\", e );\n\t\t}\n\t}\n\n\tprivate Class<? extends PersisterClassResolver> locate(ServiceRegistryImplementor registry, String className) {\n\t\treturn registry.requireService( ClassLoaderService.class ).classForName( className );\n\t}\n}\n","sourceCodeStart":32,"sourceCodeEnd":58,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/persister/internal/PersisterClassResolverInitiator.java#L32-L58","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Give the resolver a public no-arg constructor that cannot throw (do heavy setup lazily)","Confirm the class implements PersisterClassResolver and is on the runtime classpath visible to Hibernate's classloader","Verify the setting value: fully-qualified name, no typos, in every active config source","Inspect the ServiceException's cause chain for the real construction error (e.g. static init failing on missing config)"],"exampleFix":"// before: resolver with no usable constructor\npublic class ReadOnlyResolver implements PersisterClassResolver {\n    ReadOnlyResolver(DataSource ds) { ... } // no no-arg ctor -> newInstance() fails\n}\n\n// after: public no-arg constructor, heavy wiring deferred\npublic class ReadOnlyResolver implements PersisterClassResolver {\n    public ReadOnlyResolver() { }\n    // lazily initialized internals\n}","handlingStrategy":"try-catch","validationCode":"// fail fast before boot: the configured resolver must be instantiable\nString cn = cfg.getProperty(\"hibernate.persister.resolver\");\nif (cn != null) {\n    Class<?> c = Class.forName(cn);\n    if (!PersisterClassResolver.class.isAssignableFrom(c) || c.getDeclaredConstructor() == null) {\n        throw new IllegalStateException(\"Invalid PersisterClassResolver: \" + cn);\n    }\n    c.getDeclaredConstructor().newInstance(); // dry-run construction\n}","typeGuard":null,"tryCatchPattern":"try {\n    sessionFactory = cfg.buildSessionFactory();\n} catch (ServiceException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"PersisterClassResolver\")) {\n        // fix the hibernate.persister.resolver config (public no-arg ctor, on classpath)\n    }\n    throw e;\n}","preventionTips":["Give custom service implementations a public no-arg constructor that cannot throw","Refactor checks: search config files for the old FQCN when renaming resolver classes","Boot the SessionFactory in a CI smoke test so config/classpath errors never reach production"],"tags":["hibernate","orm","custom-persister","service-registry","configuration","session-factory-boot"],"backgroundTag":"custom-resolver-instantiation-failure","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}