hibernate/hibernate-orm · critical · HibernateException

Could not instantiate specified Dialect class [<dialectClass

Error message

Could not instantiate specified Dialect class [<dialectClassName>]

What it means

BasicDialectResolver (built from @Database/version metadata plus a dialect class) matched the current database name and version, then tried dialectClass.newInstance() to construct the dialect. Any Throwable other than a HibernateException from that reflective construction is wrapped as HibernateException('Could not instantiate specified Dialect class [...]') with the original throwable as cause; HibernateExceptions thrown by the constructor are rethrown unwrapped.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/jdbc/dialect/spi/BasicDialectResolver.java:80

	@Override
	public final Dialect resolveDialect(DialectResolutionInfo info) {
		final String databaseName = info.getDatabaseName();
		final int databaseMajorVersion = info.getDatabaseMajorVersion();
		final int databaseMinorVersion = info.getDatabaseMinorVersion();

		if ( nameToMatch.equalsIgnoreCase( databaseName )
				&& ( majorVersionToMatch == NO_VERSION || majorVersionToMatch == databaseMajorVersion )
				&& ( minorVersionToMatch == NO_VERSION || minorVersionToMatch == databaseMinorVersion ) ) {
			try {
				return (Dialect) dialectClass.newInstance();
			}
			catch (HibernateException e) {
				// conceivable that the dialect ctor could throw HibernateExceptions, so don't re-wrap
				throw e;
			}
			catch (Throwable t) {
				throw new HibernateException(
						"Could not instantiate specified Dialect class [" + dialectClass.getName() + "]",
						t
				);
			}
		}

		return null;
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Give the dialect class a public no-arg constructor and make the class concrete and public
  2. Read the nested cause to see whether construction failed for access, abstractness, or an internal error
  3. Ensure all classes the dialect constructor touches are on the classpath
  4. If the constructor throws a HibernateException deliberately, fix that underlying condition instead

Example fix

// before
@Database(name = "MyDB")
public class MyDbDialect extends Dialect {
    MyDbDialect(DatabaseVersion v) { super(v); } // package-private, not no-arg
}

// after
@Database(name = "MyDB")
public class MyDbDialect extends Dialect {
    public MyDbDialect() { super(DatabaseVersion.make(16, 0)); }
}
Defensive patterns

Strategy: validation

Validate before calling

// for custom @Database-annotated dialects, verify instantiability in a unit test
Class<?> c = MyDbDialect.class;
assert !Modifier.isAbstract(c.getModifiers());
assert Modifier.isPublic(c.getConstructor().getModifiers());
Dialect d = (Dialect) c.getConstructor().newInstance(); // fail at build time, not bootstrap

Try / catch

try {
    return resolver.resolveDialect(info);
} catch (HibernateException e) {
    Throwable root = e.getCause() != null ? e.getCause() : e;
    log.error("Custom dialect class failed to instantiate: {}", root, e);
    throw e;
}

Prevention

When it happens

Trigger: A custom dialect annotated with @Database + @DialectResolution registers a dialect class that is abstract, has a non-public or missing no-arg constructor, or whose constructor throws ( linkage errors, illegal state) when the database name/version matches.

Common situations: Community/custom dialects whose class requires constructor arguments; dialect classes made package-private; constructors that validate state and throw on unexpected environments; partially upgraded dialect jars missing a transitive class.

Related errors


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