hibernate/hibernate-orm · error · EnhancementException

Failed to discover types for class {className}

Error message

Failed to discover types for class {className}

What it means

Before enhancing, the enhancer runs a discovery pass: EnhancerImpl.discoverTypes() registers the class bytes in the type pool, resolves the TypeDescription, then calls enhancementContext.discoverCompositeTypes(...) to walk embeddable/composite types. Any RuntimeException in that pass (typically unresolved types when describing the class or its referenced components) is wrapped as EnhancementException('Failed to discover types for class <name>').

Source

Thrown at hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/EnhancerImpl.java:181

			throw new EnhancementException( "Failed to enhance class " + className, e );
		}
		finally {
			typePool.deregisterClassNameAndBytes( safeClassName );
		}
	}

	@Override
	public void discoverTypes(String className, byte[] originalBytes) {
		if ( originalBytes != null ) {
			typePool.registerClassNameAndBytes( className, originalBytes );
		}
		try {
			final var typeDescription = typePool.describe( className ).resolve();
			enhancementContext.registerDiscoveredType( typeDescription, Type.PersistenceType.ENTITY );
			enhancementContext.discoverCompositeTypes( typeDescription, typePool );
		}
		catch (RuntimeException e) {
			throw new EnhancementException( "Failed to discover types for class " + className, e );
		}
		finally {
			typePool.deregisterClassNameAndBytes( className );
		}
	}

	private DynamicType.Builder<?> doEnhance(
			Supplier<DynamicType.Builder<?>> builderSupplier,
			TypeDescription managedCtClass) {
		if ( alreadyEnhanced( managedCtClass ) ) {
			// The class already implements `Managed`.
			// There are 2 broad cases:
			//		1. the user manually implemented `Managed`
			//		2. the class was previously enhanced
			// In either case, look for `@EnhancementInfo` and,
			// if found, verify we can "re-enhance" the class
			final var infoAnnotation =
					managedCtClass.getDeclaredAnnotations()

View on GitHub (pinned to fad1729dce)

Solutions

  1. Read the cause chain to get the unresolved type name, then add the artifact containing it to the enhancement plugin's classpath.
  2. Give the enhancement task the same classpath as compilation plus runtime dependencies (in Gradle: classpath = sourceSets.main.runtimeClasspath).
  3. Run a clean build to rule out stale incremental class files feeding the type pool.
  4. Upgrade hibernate-core if the failure is internal to discovery rather than a missing type.

Example fix

// before (gradle)
hibernateEnhance { classes { sourceSets.main.output } } // no classpath -> discovery fails

// after
hibernateEnhance {
    classes { sourceSets.main.output }
    classpath { sourceSets.main.runtimeClasspath } // embeddables/refs resolvable
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: every type referenced by the entity must resolve on the enhancement classpath
static boolean discoverable(ClassLoader enhancerCl, String... typeNames) {
    for ( String n : typeNames ) {
        try { Class.forName( n, false, enhancerCl ); }
        catch ( ClassNotFoundException e ) { return false; }
    }
    return true;
}

Try / catch

try { enhancer.discoverTypes( className, bytes ); }
catch ( EnhancementException e ) {
    if ( e.getMessage() != null && e.getMessage().startsWith( "Failed to discover types for class" ) ) {
        // cause names the unresolved type -> fix plugin classpath, not the entity code
        buildLog.error( "enhancement classpath incomplete: {}", String.valueOf( e.getCause() ) );
    }
    throw e;
}

Prevention

When it happens

Trigger: discoverTypes(className, originalBytes) where typePool.describe(className).resolve() cannot resolve the class from registered bytes, or discoverCompositeTypes hits an embeddable/superinterface that is not on the enhancement classpath (resolve() throws on unresolved descriptions).

Common situations: Gradle/Maven enhancement plugin configured without the project's runtime dependencies, so entities referencing other modules or jars fail type discovery; partial incremental builds where a dependent class's bytes are stale; fat-jar/shaded layouts hiding referenced types from the enhancer's loader.

Related errors


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