hibernate/hibernate-orm · error · ClassLoadingException
Unable to load class [" + className + "]
Error message
Unable to load class [" + className + "]
What it means
classForName() runs Class.forName(className, true, aggregatedClassLoader) across Hibernate's aggregated class loader (Hibernate's own loader plus the thread-context loader per the configured precedence). Any failure - ClassNotFoundException, NoClassDefFoundError, ExceptionInInitializerError from static initializers, or other LinkageError - is wrapped in a ClassLoadingException carrying the class name. This is Hibernate's single choke point for name-to-Class resolution used by settings, dialect/strategy lookup, and entity reflection.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/registry/classloading/internal/ClassLoaderServiceImpl.java:93
}
// normalize adding known class-loaders...
// then the Hibernate class loader
orderedClassLoaderSet.add( ClassLoaderServiceImpl.class.getClassLoader() );
// now build the aggregated class loader...
this.aggregatedClassLoader = new AggregatedClassLoader( orderedClassLoaderSet, lookupPrecedence );
}
@Override
@SuppressWarnings("unchecked")
@Nonnull
public <T> Class<T> classForName(@Nonnull String className) {
try {
return (Class<T>) Class.forName( className, true, getAggregatedClassLoader() );
}
catch (Exception | LinkageError e) {
throw new ClassLoadingException( "Unable to load class [" + className + "]", e );
}
}
@Override
@Nullable
public URL locateResource(@Nonnull String name) {
// first we try name as a URL
try {
return new URL( name );
}
catch (Exception ignore) {
}
// if we couldn't find the resource containing a classpath:// prefix above, that means we don't have a URL
// handler for it. So let's remove the prefix and resolve against our class loader.
name = stripClasspathScheme( name );
try {View on GitHub (pinned to fad1729dce)
Solutions
- Verify the fully-qualified class name has no typos and matches the library version you actually ship
- Add the jar containing the class to the runtime classpath (check dependency scope and packaging steps)
- Run mvn dependency:tree / gradle dependencies and deduplicate conflicting versions of the artifact
- In containers/app servers, set hibernate.classLoader.tccl_lookup_precedence to never or before so the intended classloader wins
- For native images, register the class for reflection (reflection-config / @RegisterReflectionForBinding)
Example fix
// before <property name="hibernate.dialect" value="org.hibernate.dialect.PostgresSQLDialect"/> <!-- typo --> // after <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
Defensive patterns
Strategy: validation
Validate before calling
// Probe class references before boot
String dialectName = config.get("hibernate.dialect");
try {
Class.forName(dialectName, false, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Configured class not on classpath: " + dialectName, e);
} Try / catch
try {
return classLoaderService.classForName(className);
} catch (ClassLoadingException e) {
Throwable cause = e.getCause(); // ClassNotFoundException / LinkageError - the real reason
log.warn("Cannot load {} ({}); check classpath and dependency scope", className, cause);
throw e;
} Prevention
- Ship a startup probe that Class.forName-loads every class referenced in Hibernate properties
- Keep a single consistent Hibernate version across modules; run dependency:tree in CI
- For native images, generate reflection metadata for all reflectively loaded classes
When it happens
Trigger: Any Hibernate setting or API that takes a class name: hibernate.dialect=my.CustomDialect, a custom ConnectionProvider/UserType/IdentifierGenerator class, StrategySelector.selectStrategyImplementor, or class metadata loading when the named class is not loadable by any of the aggregated loaders.
Common situations: Missing jar on the runtime classpath (provided-scope dependency not shipped); typo in a fully-qualified class name; duplicated or older jar versions hiding the class; app-server / fat-jar / shaded-jar classloader visibility problems; GraalVM native image missing reflection metadata; a static initializer of the class throwing.
Related errors
- %s
- Could not find a FormatMapper for the JSON format, which is
- Unable to build configuration.xml JAXBContext
- Unknown TcclLookupPrecedence - {}
- Unable to resolve name [{}] as strategy [{}]
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/5bb51273b4452c72.
Report an issue: GitHub.