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

  1. Treat the discriminator as a leaf: compare it with TYPE(p) = :subtype or p.type = DiscriminatorValue, never navigate through it
  2. If you need fields of the subtype, use TREAT(p AS Subtype).attribute or a join to the subclass entity instead
  3. 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

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


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