hibernate/hibernate-orm · error · HibernateException
Unable to locate named class " + string
Error message
Unable to locate named class " + string
What it means
ClassJavaType.fromString hydrates a Class-typed attribute by loading the class named in the column via ReflectHelper.classForName(). ClassNotFoundException is wrapped in HibernateException('Unable to locate named class <name>') — note the original exception is not chained, so the message is the only clue. Thrown while loading the entity row.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClassJavaType.java:54
return true;
}
@Override
public String toString(Class<?> value) {
return value.getName();
}
@Override
public Class<?> fromString(CharSequence string) {
if ( string == null ) {
return null;
}
try {
return ReflectHelper.classForName( string.toString() );
}
catch ( ClassNotFoundException e ) {
throw new HibernateException( "Unable to locate named class " + string );
}
}
@Override
public <X> X unwrap(Class<?> value, Class<X> type, WrapperOptions options) {
if ( value == null ) {
return null;
}
if ( Class.class.isAssignableFrom( type ) ) {
return type.cast( value );
}
if ( String.class.isAssignableFrom( type ) ) {
return type.cast( toString( value ) );
}
throw unknownUnwrap( type );
}
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Update the stored names (UPDATE ... SET type_name = 'com.new.Fqn') or add a converter mapping legacy names to current classes.
- Restore or deploy the artifact containing the missing class before loading those rows.
- Quarantine offending rows with a WHERE filter until data is fixed.
Example fix
-- before: class moved from com.acme.OldType to com.acme.NewType SELECT * FROM items; -- hydrate throws HibernateException: Unable to locate named class com.acme.OldType -- after UPDATE items SET type_name = 'com.acme.NewType' WHERE type_name = 'com.acme.OldType';
Defensive patterns
Strategy: try-catch
Validate before calling
static boolean classResolves(String fqn) {
try { Class.forName(fqn, false, Thread.currentThread().getContextClassLoader()); return true; }
catch (ClassNotFoundException e) { return false; }
} Try / catch
try {
return session.find(Item.class, id);
} catch (HibernateException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unable to locate named class")) {
// note: the ClassNotFoundException cause is NOT chained
throw new DataIntegrityException("Stale class name in row " + id + ": " + e.getMessage(), e);
}
throw e;
} Prevention
- Treat stored class names as schema: run data migrations with package refactors.
- Validate stored names against the classpath in CI for seed/reference tables.
- Prefer short discriminator strings over full class names in columns.
When it happens
Trigger: Rows whose class-name column references a class missing from the runtime classpath: the class was renamed/moved during refactoring, an optional module is not deployed, or environments run different artifacts.
Common situations: Package refactors without updating stored class names; removal of a deprecated subtype while old rows still reference it; shaded/relocated jars in production; dev machine has the class but CI/prod does not.
Related errors
- Multiple active MetadataBuilder definitions were discovered
- Unable to determine JAR Url from <url>. Cause: <cause>
- Could not resolve jar-file: <jarFileReference>
- Could not find specified jar-file: <jarFileReference>
- Jakarta Validation API was not available, but 'callback' val
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/c92abb0a8c0221b2.
Report an issue: GitHub.