{"record":{"id":"2b5f412981e7b65c","repo":"hibernate/hibernate-orm","slug":"could-not-instantiate-event-listener","errorCode":null,"errorMessage":"Could not instantiate event listener '{}'","messagePattern":"Could not instantiate event listener '(.+?)'","errorType":"exception","errorClass":"HibernateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java","lineNumber":528,"sourceCode":"\t\t\tEventType<T> eventType) {\n\t\tfinal var eventListenerGroup = eventListenerRegistry.getEventListenerGroup( eventType );\n\t\tfor ( String listenerImpl : splitAtCommas( listeners ) ) {\n\t\t\tfinal var listener = instantiate( listenerImpl, classLoaderService );\n\t\t\tfinal var baseListenerInterface = eventType.baseListenerInterface();\n\t\t\tif ( !baseListenerInterface.isInstance( listener ) ) {\n\t\t\t\tthrow new HibernateException( \"Event listener '\" + listenerImpl\n\t\t\t\t\t\t+ \"' must implement '\" + baseListenerInterface.getName() + \"'\");\n\t\t\t}\n\t\t\teventListenerGroup.appendListener( baseListenerInterface.cast( listener ) );\n\t\t}\n\t}\n\n\tprivate static Object instantiate(String listenerImpl, ClassLoaderService classLoaderService) {\n\t\ttry {\n\t\t\treturn classLoaderService.classForName( listenerImpl ).newInstance();\n\t\t}\n\t\tcatch (Exception e) {\n\t\t\tthrow new HibernateException( \"Could not instantiate event listener '\" + listenerImpl + \"'\", e );\n\t\t}\n\t}\n\n\t@Override\n\tpublic void visitRegisteredComponents(Consumer<Component> consumer) {\n\t\tcomposites.forEach( consumer );\n\t}\n\n\t@Override\n\tpublic Component getGenericComponent(Class<?> componentClass) {\n\t\treturn genericComponentsMap.get( componentClass );\n\t}\n\n\t@Override\n\tpublic DiscriminatorType<?> resolveEmbeddableDiscriminatorType(\n\t\t\tClass<?> embeddableClass,\n\t\t\tSupplier<DiscriminatorType<?>> supplier) {\n\t\treturn embeddableDiscriminatorTypesMap.computeIfAbsent( embeddableClass, k -> supplier.get() );","sourceCodeStart":510,"sourceCodeEnd":546,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/internal/MetadataImpl.java#L510-L546","documentation":"Hibernate throws this while a SessionFactory initializes, when it cannot reflectively instantiate a custom event listener. Listeners are registered via properties named hibernate.event.listener.<event-type> (e.g. hibernate.event.listener.load) whose value is a comma-separated list of fully-qualified class names; MetadataImpl.initSessionFactory loads each class with ClassLoaderService and calls its no-arg constructor. Any failure (class not found, no public no-arg constructor, abstract class, or a constructor that throws) is wrapped in this HibernateException with the original cause attached.","triggerScenarios":"SessionFactory bootstrap scans all settings starting with 'hibernate.event.listener.' and calls classLoaderService.classForName(listenerImpl).newInstance(); the error fires when the class is missing from the classpath, is abstract or an interface, has no accessible no-arg constructor, or its constructor throws an exception.","commonSituations":"Listener class renamed/moved during an upgrade but the property still holds the old name; listener lives in a module not deployed with the persistence unit; constructor expects injected dependencies and throws NPE; typo in the class name; property copied from another application where the class exists.","solutions":["Check the exact fully-qualified class name in the hibernate.event.listener.<event-type> property and that the class is on the runtime classpath","Give the listener a public no-argument constructor (classForName(...).newInstance() requires it)","Unwrap and inspect the nested cause: ClassNotFoundException means classpath/typo, InvocationTargetException means the constructor itself threw","If the listener needs dependencies, use a no-arg constructor with lazy lookup or register the listener programmatically via EventListenerRegistry instead of the property","Verify in a scratch test: Class.forName(name).getConstructor().newInstance()"],"exampleFix":"// before: hibernate.cfg.xml property\n// hibernate.event.listener.load = com.acme.AuditLoadListener\n// where AuditLoadListener only defines AuditLoadListener(DataSource ds)\n\n// after: add a public no-arg constructor to the listener\npublic AuditLoadListener() {\n    this.dataSource = DataSourceHolder.lookup(); // lazy, no injection needed\n}\npublic AuditLoadListener(DataSource ds) {\n    this.dataSource = ds;\n}","handlingStrategy":"validation","validationCode":"// before building the SessionFactory, check every configured listener\nstatic void checkEventListeners(Properties props) throws Exception {\n    for (String name : props.stringPropertyNames()) {\n        if (!name.startsWith(\"hibernate.event.listener.\")) continue;\n        for (String cls : props.getProperty(name).split(\",\")) {\n            Class<?> c = Class.forName(cls.trim());\n            if (c.isInterface() || Modifier.isAbstract(c.getModifiers()))\n                throw new IllegalStateException(\"Listener is abstract/interface: \" + cls);\n            c.getConstructor(); // fails fast without public no-arg ctor\n        }\n    }\n}","typeGuard":"static boolean isInstantiableListener(String fqcn) {\n    try {\n        Class<?> c = Class.forName(fqcn);\n        return !c.isInterface() && !Modifier.isAbstract(c.getModifiers())\n            && java.lang.reflect.Modifier.isPublic(c.getConstructor().getModifiers());\n    } catch (ReflectiveOperationException e) { return false; }\n}","tryCatchPattern":"try {\n    SessionFactory sf = metadata.buildSessionFactory();\n} catch (HibernateException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Could not instantiate event listener\")) {\n        Throwable cause = e.getCause();\n        // ClassNotFoundException -> classpath/typo; InvocationTargetException -> ctor bug\n        log.error(\"Bad event listener config: {}\", cause, e);\n    }\n    throw e;\n}","preventionTips":["Keep a single constant for each listener FQCN used in properties so renames stay consistent","Prefer registering listeners programmatically via EventListenerRegistry (Integrator) over string properties","Give every listener a public no-arg constructor and resolve collaborators lazily","Add a SessionFactory-bootstrap integration test so bad listener config fails in CI, not in production"],"tags":["hibernate","event-listener","reflection","configuration","bootstrap"],"backgroundTag":"reflection-instantiation-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}