hibernate/hibernate-orm · error · RuntimeException
Unable to instantiate StatementObserver - {}
Error message
Unable to instantiate StatementObserver - {} What it means
SessionFactoryOptionsBuilder reads the hibernate.statement_observer setting, which accepts a StatementObserver instance, a Class object, or a class-name String. When a Class is supplied, Hibernate reflectively calls its public no-arg constructor (impl.getConstructor().newInstance()); any failure is rethrown as this RuntimeException naming the class, with the original cause attached.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java:605
}
@Nullable
private StatementObserver interpretStatementObserver(Map<String, Object> settings) {
var setting = settings.get( JdbcSettings.STATEMENT_OBSERVER );
if ( setting == null ) {
return null;
}
if ( setting instanceof StatementObserver observer ) {
return observer;
}
if ( setting instanceof Class<?> impl ) {
try {
return (StatementObserver) impl.getConstructor().newInstance();
}
catch (Exception e) {
throw new RuntimeException( "Unable to instantiate StatementObserver - " + impl.getName(), e );
}
}
try {
var namedImpl = Class.forName( setting.toString() );
return (StatementObserver) namedImpl.getConstructor().newInstance();
}
catch (Exception e) {
throw new RuntimeException( "Unable to instantiate StatementObserver - " + setting, e );
}
}
@Nullable
private TimeZone getJdbcTimeZone(Object jdbcTimeZoneValue) {
if ( jdbcTimeZoneValue instanceof TimeZone timeZone ) {
return timeZone;
}
else if ( jdbcTimeZoneValue instanceof ZoneId zoneId ) {View on GitHub (pinned to fad1729dce)
Solutions
- Add a public no-argument constructor to the observer class
- Read the nested cause: InvocationTargetException means the constructor body threw — fix that exception
- Prefer passing a fully-built StatementObserver instance via SessionFactoryBuilder#applyStatementObserver (or the setting) instead of a Class, so construction is under your control
- Keep construction side-effect free and resolve collaborators lazily
Example fix
// before:
props.put("hibernate.statement_observer", MetricsObserver.class);
// MetricsObserver only has MetricsObserver(MeterRegistry registry)
// after: pass a ready instance
MeterRegistry registry = Metrics.registries();
props.put("hibernate.statement_observer", new MetricsObserver(registry)); Defensive patterns
Strategy: validation
Validate before calling
// if you register a Class, verify its constructor shape first
static boolean hasPublicNoArgCtor(Class<?> c) {
try { return Modifier.isPublic(c.getConstructor().getModifiers()); }
catch (NoSuchMethodException e) { return false; }
}
if (!hasPublicNoArgCtor(MetricsObserver.class)) throw new IllegalStateException("observer needs public no-arg ctor");
props.put("hibernate.statement_observer", MetricsObserver.class); Type guard
static boolean isStatementObserverSettingValid(Object value) {
if (value instanceof StatementObserver || value == null) return true;
if (value instanceof Class<?> c) return StatementObserver.class.isAssignableFrom(c) && hasPublicNoArgCtor(c);
return false; // strings handled by Class.forName path
} Try / catch
try {
sessionFactory = new Configuration().addProperties(props).buildSessionFactory();
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unable to instantiate StatementObserver")) {
// fix config; e.getCause() tells why construction failed
}
throw e;
} Prevention
- Pass a pre-built StatementObserver instance instead of a Class whenever possible
- Keep observer constructors side-effect free; resolve collaborators lazily
- Cover the property in a bootstrap test so it fails before deployment
When it happens
Trigger: Setting hibernate.statement_observer to a Class that is abstract, lacks a public no-arg constructor, or whose constructor throws; the failure happens during SessionFactoryOptions building, i.e. at SessionFactory bootstrap.
Common situations: Observer written with only a constructor taking arguments (e.g. a metrics registry); constructor not public; constructor body throws because it expects container injection; observer class uses optional dependencies absent in the test classpath.
Related errors
- Could not instantiate event listener '{}'
- Could not instantiate named dialect class [%s]
- Unable to instantiate named dialect resolver [<resolverImplN
- Unable to instantiate specified event listener class:
- Unable to instantiate specified BeanContainer
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/11bd8c31431b92c2.
Report an issue: GitHub.