hibernate/hibernate-orm · error · IllegalStateException
Entity discriminator cannot be de-referenced
Error message
Entity discriminator cannot be de-referenced
What it means
The discriminator column of an entity (its 'class' / DTYPE path, exposed as a SqmPathSource with the reserved role "type") is a scalar marker, not an embeddable or association. If HQL/Criteria navigation tries to resolve a sub-attribute underneath the discriminator path (findSubPathSource), Hibernate throws IllegalStateException because there is nothing to navigate into.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AbstractDiscriminatorSqmPathSource.java:31
import static jakarta.persistence.metamodel.Bindable.BindableType.SINGULAR_ATTRIBUTE;
import static jakarta.persistence.metamodel.Type.PersistenceType.BASIC;
import static org.hibernate.metamodel.mapping.EntityDiscriminatorMapping.DISCRIMINATOR_ROLE_NAME;
/**
* Abstract SqmPathSource implementation for discriminators
*
* @author Steve Ebersole
*/
public abstract class AbstractDiscriminatorSqmPathSource<D> extends AbstractSqmPathSource<D>
implements ReturnableType<D>, SqmDomainType<D> {
public AbstractDiscriminatorSqmPathSource(DomainType<D> domainType) {
super( DISCRIMINATOR_ROLE_NAME, null, domainType, SINGULAR_ATTRIBUTE );
}
@Override
public SqmPathSource<?> findSubPathSource(String name) {
throw new IllegalStateException( "Entity discriminator cannot be de-referenced" );
}
@Override
@Nonnull
public PersistenceType getPersistenceType() {
return BASIC;
}
@Override
@Nonnull
public Class<D> getJavaType() {
return getExpressibleJavaType().getJavaTypeClass();
}
@Override
public @Nullable SqmDomainType<D> getSqmType() {
return this;
}View on GitHub (pinned to fad1729dce)
Solutions
- Treat the discriminator as a leaf: compare it with TYPE(p) = :subtype or p.type = DiscriminatorValue, never navigate through it
- If you need fields of the subtype, use TREAT(p AS Subtype).attribute or a join to the subclass entity instead
- In generic path-walking code, skip SqmPathSource instances whose getPathName() equals "type"/"class" or that extend AbstractDiscriminatorSqmPathSource
Example fix
// before (HQL) select p.type.name from Person p // illegal dereference // after select p.name from TREAT(p as Employee) p // or select type(p) from Person p // compare, don't navigate
Defensive patterns
Strategy: validation
Validate before calling
// Before navigating a path source, ensure it is not a discriminator
String name = pathSource.getPathName();
if ("type".equals(name) || "class".equals(name)) {
return; // discriminator: leaf node, not navigable
} Type guard
static boolean isDiscriminatorSource(org.hibernate.query.sqm.tree.SqmPathSource<?> src) {
return src instanceof org.hibernate.metamodel.model.domain.internal.AbstractDiscriminatorSqmPathSource<?>;
} Try / catch
try {
SqmPathSource<?> sub = source.findSubPathSource(name);
} catch (IllegalStateException e) {
if ("Entity discriminator cannot be de-referenced".equals(e.getMessage())) {
// skip discriminator navigation; treat as leaf
} else throw e;
} Prevention
- Never generate paths under the discriminator; only compare with it
- Use TREAT() or joins to reach subclass state
- Add a query-builder test suite over an inheritance-mapped test entity
When it happens
Trigger: HQL/Criteria like select p.type.name from Person p, or root.get("type").get("name"), or sqmPath.get("class").get(<anything>) — any dereference of the discriminator path for a SINGLE_TABLE/JOINED inheritance discriminator. Also generated code that recursively expands every path source of an entity, including the synthetic discriminator source.
Common situations: Query builders / GraphQL-JVM style resolvers that walk all SqmPathSources of an entity and call findSubPathSource on each name. Assuming the JPA 3.2 TYPE() function returns a navigable object rather than a Class reference. Copying entity graph expansions that work on embeddables onto the discriminator.
Related errors
- Entity discriminator cannot be de-referenced
- Could not resolve attribute '%s' of '%s' due to the attribut
- Cannot apply TREAT operator to discriminator path
- Basic-value cannot be treated (downcast)
- Root entity '<entityName>' is annotated '@DiscriminatorOptio
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/8e8ab8d19cae5ba1.
Report an issue: GitHub.