hibernate/hibernate-orm · error · EnhancementException
Unable to perform extended enhancement - No unique field [%s
Error message
Unable to perform extended enhancement - No unique field [%s] defined by [%s]
What it means
During extended enhancement, after resolving the owner type of a field instruction, FieldAccessEnhancer.findField() looks for exactly one declared field matching both name and descriptor (named(name).and(hasDescriptor(desc))) walking the hierarchy. If the filtered list does not contain exactly one element - typically zero because the owner type resolved from the classpath is a different version whose field has a different descriptor/signature - it throws EnhancementException('No unique field [<name>] defined by [<owner>]').
Source
Thrown at hibernate-core/src/main/java/org/hibernate/bytecode/enhance/internal/bytebuddy/FieldAccessEnhancer.java:131
}
private TypeDescription findDeclaredType(String name) {
//Classpool#describe does not accept '/' in the description name as it expects a class name
final String cleanedName = name.replace( '/', '.' );
final var resolution = classPool.describe( cleanedName );
if ( !resolution.isResolved() ) {
throw new EnhancementException( String.format(
"Unable to perform extended enhancement - Unable to locate [%s]",
cleanedName
) );
}
return resolution.resolve();
}
private AnnotatedFieldDescription findField(TypeDescription declaredOwnedType, String name, String desc) {
final var fields = findFields( declaredOwnedType, name, desc );
if ( fields.size() != 1 ) {
throw new EnhancementException( String.format(
"Unable to perform extended enhancement - No unique field [%s] defined by [%s]",
name,
declaredOwnedType.getName()
) );
}
return new AnnotatedFieldDescription( enhancementContext, fields.getOnly() );
}
private static @Nonnull FieldList<?> findFields(TypeDescription declaredOwnedType, String name, String desc) {
TypeDefinition ownerType = declaredOwnedType;
final var fieldFilter = named( name ).and( hasDescriptor( desc ) );
FieldList<?> fields = ownerType.getDeclaredFields().filter( fieldFilter );
// Look in the superclasses if necessary
while ( fields.isEmpty() && ownerType.getSuperClass() != null ) {
ownerType = ownerType.getSuperClass();
fields = ownerType.getDeclaredFields().filter( fieldFilter );
}
return fields;View on GitHub (pinned to fad1729dce)
Solutions
- Align the enhancement classpath with the exact versions the entity classes were compiled against (dependencyManagement/lockfile) so the resolved field descriptor matches.
- Check for duplicate classes (same FQCN) across jars on the enhancement classpath and evict the stale copy.
- Disable extended enhancement if it is not strictly required - the error only occurs on that path.
- Use the message's owner type + field name to identify which artifact must be version-aligned.
Example fix
# before
# entity compiled against lib-2.0 (field: Optional<X> x), enhancement classpath has lib-1.9 (field: X x)
# -> findFields matches 0 -> 'No unique field [x] defined by [com.lib.Owner]'
# after
# gradle
configurations.enhanceClasspath { resolutionStrategy { force 'com.lib:lib:2.0' } } # or align via platform/BOM Defensive patterns
Strategy: fallback
Validate before calling
// pre-flight: the enhancement classpath must contain the same owner-type versions the classes were compiled against
static boolean fieldDescriptorsMatch(ClassLoader cl, String owner, String field, String expectedDesc) throws Exception {
Class<?> c = Class.forName( owner, false, cl );
for ( var f : c.getDeclaredFields() ) {
if ( f.getName().equals( field ) ) { return descriptorOf( f.getType() ).equals( expectedDesc ); }
}
return false;
} Prevention
- Lock dependency versions (BOM/platform) so compile and enhancement classpaths cannot diverge.
- Detect duplicate classes across jars on the enhancement classpath and evict stale copies.
- Keep extended enhancement off unless required - findField() uniqueness checks run only on that path.
When it happens
Trigger: enableExtendedEnhancement(true) while the classpath holds a different version of the owner type than the one the class was compiled against: a field's type changed between versions (so the descriptor differs), the field was renamed/removed, or duplicate classes with conflicting field signatures are both visible.
Common situations: Conflicting dependency versions on the enhancement classpath (the classic 'two versions of the same library' problem surfacing as a descriptor mismatch); upgrading one library whose API changed a field type while the enhancer resolves the other; shaded jars bundling stale copies of a class.
Related errors
- Unable to perform extended enhancement - Unable to locate [%
- Annotation '@" + annotation.annotationType().getName() + "'
- Failed to discover types for class {className}
- Unable to initialize EventType map
- Multiple active MetadataBuilder definitions were discovered
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/5effa4e7678ff1eb.
Report an issue: GitHub.