hibernate/hibernate-orm · error · MappingException

proxy must be either an interface, or the class itself: {ent

Error message

proxy must be either an interface, or the class itself: {entityName}

What it means

Same validation as the root-entity case, but performed while EntityRepresentationStrategyPojoStandard walks the subclass closure of the hierarchy: for every subclass with a @Proxy/proxy declaration whose proxy class differs from the subclass's own mapped class, that class must be an interface. A concrete class in a subclass's proxy mapping aborts SessionFactory creation with this MappingException naming the offending subclass entity.

Source

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

		if ( proxyInterface != null && ! mappedClass.equals( proxyInterface ) ) {
			if ( ! proxyInterface.isInterface() ) {
				throw new MappingException( "proxy must be either an interface, or the class itself: "
											+ bootDescriptor.getEntityName() );
			}
			proxyInterfaces.add( proxyInterface );
		}

		if ( mappedClass.isInterface() ) {
			proxyInterfaces.add( mappedClass );
		}

		for ( var subclass : bootDescriptor.getSubclasses() ) {
			final var subclassProxy = subclass.getProxyInterface();
			final var subclassClass = subclass.getMappedClass();
			if ( subclassProxy != null && !subclassClass.equals( subclassProxy ) ) {
				if ( !subclassProxy.isInterface() ) {
					throw new MappingException( "proxy must be either an interface, or the class itself: "
												+ subclass.getEntityName() );
				}
				proxyInterfaces.add( subclassProxy );
			}
		}

		proxyInterfaces.add( HibernateProxy.class );

		return proxyInterfaces;
	}

	private static ProxyFactory instantiateProxyFactory(
			PersistentClass bootDescriptor,
			BytecodeProvider bytecodeProvider,
			RuntimeModelCreationContext creationContext,
			Method proxyGetIdentifierMethod,
			Method proxySetIdentifierMethod,
			Class<?> mappedClass,

View on GitHub (pinned to fad1729dce)

Solutions

  1. Change the subclass's @Proxy(proxyClass=...) value to an interface the subclass implements
  2. Remove the redundant @Proxy on the subclass if the root declaration already covers it
  3. Use @Proxy(lazy = false) on that subclass when proxying is not wanted

Example fix

// before
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class BillingDocument { ... }

@Entity
@Proxy(proxyClass = Invoice.class)   // Invoice is a class, not an interface
public class Invoice extends BillingDocument { ... }

// after
@Entity
@Proxy(proxyClass = InvoiceDto.class) // interface implemented by Invoice
public class Invoice extends BillingDocument implements InvoiceDto { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Validate the whole hierarchy, not just the root
for ( Class<?> c : allMappedClassesInHierarchy() ) {
    Proxy p = c.getAnnotation(Proxy.class);
    if ( p != null && !void.class.equals(p.proxyClass()) && !p.proxyClass().isInterface() && !p.proxyClass().equals(c) ) {
        throw new IllegalStateException("Subclass " + c + " declares a non-interface @Proxy class");
    }
}

Type guard

static boolean isValidSubclassProxy(Class<?> subclass, Class<?> proxyClass) {
    return proxyClass == null || proxyClass.isInterface() || proxyClass.equals(subclass);
}

Try / catch

try {
    emf = Persistence.createEntityManagerFactory("pu");
}
catch ( org.hibernate.mapping.MappingException e ) {
    if ( e.getMessage() != null && e.getMessage().startsWith("proxy must be either an interface") ) {
        // message names the subclass entity - fix that subclass's @Proxy/XML proxy attribute
        throw new ConfigurationError("Invalid proxy mapping in hierarchy: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: @Proxy(proxyClass = ConcreteSubclassHelper.class) on a subclass in a SINGLE_TABLE/JOINED hierarchy; XML <subclass ... proxy="..."> referencing a class; superclass-level proxy interfaces fine but one branch of the hierarchy redeclares @Proxy with a class.

Common situations: Large inheritance hierarchies where each subclass declares its own proxy interface and one was refactored from interface to abstract class; merging teams' mappings where conventions differ; proxy annotation inherited/copy-pasted from sibling subclasses.

Related errors


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