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 );
	}

	@Override

View on GitHub (pinned to fad1729dce)

Solutions

  1. Update the stored names (UPDATE ... SET type_name = 'com.new.Fqn') or add a converter mapping legacy names to current classes.
  2. Restore or deploy the artifact containing the missing class before loading those rows.
  3. 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

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


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