hibernate/hibernate-orm · error · HibernateException

%s methods of lazy classes cannot be final: %s#%s

Error message

%s methods of lazy classes cannot be final: %s#%s

What it means

A HibernateException raised at bootstrap by validateGetterSetterMethodProxyability inside EntityRepresentationStrategyPojoStandard: when an entity is mapped as lazy/proxyable, Hibernate must be able to override the access methods of its attributes, so a final getter or setter makes proxy generation impossible. The message states 'Getter'/'Setter' methods of lazy classes cannot be final and names the declaring class and method.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/internal/EntityRepresentationStrategyPojoStandard.java:382

			return identifierPropertyAccess;
		}
		else {
			final var propertyAccess = propertyAccessMap.get( bootAttributeDescriptor.getName() );
			if ( propertyAccess != null ) {
				return propertyAccess;
			}
			else if ( mapsIdRepresentationStrategy != null ) {
				return mapsIdRepresentationStrategy.resolvePropertyAccess( bootAttributeDescriptor );
			}
			else {
				return null;
			}
		}
	}

	private static void validateGetterSetterMethodProxyability(String getterOrSetter, Method method ) {
		if ( method != null && isFinal( method.getModifiers() ) ) {
			throw new HibernateException(
					String.format(
							"%s methods of lazy classes cannot be final: %s#%s",
							getterOrSetter,
							method.getDeclaringClass().getName(),
							method.getName()
					)
			);
		}
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove 'final' from the reported getter/setter (and from the class if it is final) so the proxy can subclass it
  2. For Kotlin, apply the all-open compiler plugin with the JPA targets (@Entity, @MappedSuperclass, @Embeddable) so classes and members are generated open
  3. Alternatively disable proxy-based laziness for this entity with @Proxy(lazy = false) if you accept eager loading
  4. Re-run SessionFactory creation - the validation fails fast at startup

Example fix

// Kotlin - before: final by default
@Entity
class Person(@get:Column val name: String)   // getter is final -> HibernateException

// Kotlin - after: all-open plugin makes @Entity classes open
// build.gradle.kts: plugins { kotlin("plugin.jpa") version "..." }
@Entity
class Person(@get:Column open val name: String)

// Java - before/after
public final String getName() { ... }   // -> remove 'final'
public String getName() { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast if a lazy-mapped entity has final accessors
for ( EntityType<?> t : emf.getMetamodel().getEntities() ) {
    if ( isLazyMapped(t) ) {
        for ( java.lang.reflect.Method m : t.getJavaType().getMethods() ) {
            if ( ( m.getName().startsWith("get") || m.getName().startsWith("set") )
                    && Modifier.isFinal(m.getModifiers()) ) {
                throw new IllegalStateException("Final accessor blocks proxy: " + m);
            }
        }
    }
}

Type guard

static boolean proxyableAccessor(Method m) { return !Modifier.isFinal(m.getModifiers()); }

Try / catch

try {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
}
catch ( org.hibernate.HibernateException e ) {
    if ( e.getMessage() != null && e.getMessage().contains("cannot be final") ) {
        throw new ConfigurationError("Remove 'final' from the named accessor or disable @Proxy lazy - " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: An entity with lazy=true/@Proxy(lazy=true) whose attribute getter or setter is declared final; Kotlin entity classes and properties, which are final by default unless marked open or compiled with the kotlin-allopen compiler plugin; Java classes hardened with 'final' on accessors for immutability.

Common situations: Introducing Kotlin entities without the kotlin.plugin.jpa/all-open plugin; adding 'final' to accessors during an immutability refactor; bytecode-obfuscated or code-generated models with final accessors; enabling lazy proxying on previously eagerly-loaded hierarchies.

Related errors


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