hibernate/hibernate-orm · error · EnhancementException

Enhancement of [%s] failed because no underlying field named

Error message

Enhancement of [%s] failed because no underlying field named [%s] exists for property accessor method [%s] (ensure all property accessor methods have a matching field)

What it means

During enhancement Hibernate treats JavaBeans-style accessors (get/set/is methods) as property accessors and expects a backing field of the derived name. When no such field exists, behavior depends on the UnsupportedEnhancementStrategy: SKIP logs propertyAccessorNoFieldSkip and moves on, but FAIL (the case here) throws EnhancementException telling you which class/accessor lacked the field - the method looks like an accessor but there is nothing to instrument.

Source

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

		return false;
	}

	@SuppressWarnings("deprecation")
	private static boolean handleMissingField(
			TypeDescription managedCtClass,
			UnsupportedEnhancementStrategy strategy,
			MethodDescription methodDescription,
			String fieldName) {
		return switch ( strategy ) {
			case SKIP -> {
				ENHANCEMENT_LOGGER.propertyAccessorNoFieldSkip(
						managedCtClass.getName(),
						fieldName,
						methodDescription.getName()
				);
				yield true;
			}
			case FAIL -> throw new EnhancementException( String.format(
					"Enhancement of [%s] failed because no underlying field named [%s] exists for property accessor method [%s]"
					+ " (ensure all property accessor methods have a matching field)",
					managedCtClass.getName(),
					fieldName,
					methodDescription.getName()
			) );
			case LEGACY -> throw new AssertionFailure( "Unexpected strategy at this point: " + strategy );
		};
	}

	private static @Nullable String propertyName(MethodDescription methodDescription) {
		return getJavaBeansFieldName( trimGetterName( methodDescription.getActualName() ) );
	}

	private static @Nonnull String trimGetterName(String methodName) {
		if ( methodName.startsWith( "get" ) || methodName.startsWith( "set" ) ) {
			return methodName.substring( 3 );
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Rename the method so it no longer matches the JavaBeans accessor pattern (e.g. computeTotal(), nameOf()) - Hibernate then ignores it during enhancement.
  2. Add the matching field the accessor exposes, so instrumentation has something to attach to.
  3. Configure the unsupported-enhancement strategy to SKIP so these methods are logged (propertyAccessorNoFieldSkip) and enhancement continues instead of failing.
  4. Audit with the message's triple (class, fieldName, methodName): propertyName() derives the field name from the method name, so the mismatch is usually visible immediately.

Example fix

// before
public class Invoice {
    public BigDecimal getTotal() { return lines.stream().map(Line::getAmt).reduce(ZERO, ADD); }
    // no field 'total' -> EnhancementException with strategy FAIL
}

// after
public class Invoice {
    public BigDecimal computeTotal() { return lines.stream().map(Line::getAmt).reduce(ZERO, ADD); }
}
Defensive patterns

Strategy: fallback

Validate before calling

// before enhancement, flag accessor-named methods without backing fields
for ( var m : entityClass.getDeclaredMethods() ) {
    java.util.Optional<String> field = javaBeansFieldOf( m.getName() ); // getFoo/isFoo/setFoo -> foo
    if ( field.isPresent() && java.util.Arrays.stream( entityClass.getDeclaredFields() )
            .noneMatch( f -> f.getName().equals( field.get() ) ) ) {
        issues.add( entityClass.getName() + "#" + m.getName() + " has no field " + field.get() );
    }
}

Prevention

When it happens

Trigger: An entity (or extended-enhancement target) has a method named like a getter/setter (getTotal(), isValid(), setName(...)) with no corresponding field 'total'/'valid'/'name' - computed or delegated properties - while the enhancement strategy is FAIL.

Common situations: DTO-like entities with calculated getters; lombok @Getter on a parent interface; methods delegating to a wrapped object; renaming a field without renaming its accessor (or vice versa) during a refactor; boolean 'isXxx' naming where the field is 'xxxFix' style.

Related errors


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