hibernate/hibernate-orm · error · IllegalStateException
Discriminator cannot be de-referenced
Error message
Discriminator cannot be de-referenced
What it means
DiscriminatorSqmPath is the SQM node produced by HQL TYPE(e) / criteria Root.type(). A discriminator holds a scalar class value and is not an attribute-bearing path, so every navigation method on the interface is a default method throwing IllegalStateException('Discriminator cannot be de-referenced'). resolvePathPart is the one hit from the HQL parser when the path continues after type(...), i.e. any attempt to navigate further from the discriminator at query-creation time.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/spi/DiscriminatorSqmPath.java:49
import java.util.Collection;
import java.util.Map;
/**
* Commonality between entity and any discriminators
*
* @author Steve Ebersole
*/
public interface DiscriminatorSqmPath<T> extends SqmPath<T> {
@Override
default void appendHqlString(StringBuilder hql, SqmRenderContext context) {
hql.append( "type(" );
getLhs().appendHqlString( hql, context );
hql.append( ')' );
}
@Override
default SqmPath<?> resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {
throw new IllegalStateException( "Discriminator cannot be de-referenced" );
}
@Nonnull
@Override
default <Y> SqmPath<Y> get(@Nonnull String attributeName) {
throw new IllegalStateException( "Discriminator cannot be de-referenced" );
}
@Nonnull
@Override
default <Y> SqmPath<Y> get(@Nonnull SingularAttribute<? super T, Y> attribute) {
throw new IllegalStateException( "Discriminator cannot be de-referenced" );
}
@Nonnull
@Override
default <E, C extends Collection<E>> SqmPluralPath<C, E> get(@Nonnull PluralAttribute<? super T, C, E> collection) {
throw new IllegalStateException( "Discriminator cannot be de-referenced" );View on GitHub (pinned to fad1729dce)
Solutions
- Use the discriminator only where a class literal is legal: type(o) = FullTimeEmployee or type(o) in (...).
- To filter by type, bind a Class parameter: ... where type(o) = :type.
- Select it directly when you need the value: select type(o) from Order o.
- Use TREAT(o AS SubType) when you need subclass state, never type(o).attribute.
Example fix
// before select o from Order o where type(o).priority = 'HIGH' // after - compare the discriminator itself, or treat to reach subclass state select o from Order o where type(o) = RushOrder select o from Order o where treat(o as RushOrder).priority = 'HIGH'
Defensive patterns
Strategy: type-guard
Validate before calling
// reject 'type(...).' navigation before creating the query
if (hql.matches("(?is).*type\\s*\\([^)]*\\)\\s*\\..*")) {
throw new IllegalArgumentException("type(...) cannot be de-referenced in: " + hql);
} Type guard
static boolean isDiscriminator(SqmPath<?> path) {
return path instanceof org.hibernate.query.sqm.spi.DiscriminatorSqmPath;
} Try / catch
try {
return em.createQuery(hql, Order.class).getResultList();
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("Discriminator")) {
throw new IllegalArgumentException("type() is not navigable - compare it or use TREAT instead", e);
}
throw e;
} Prevention
- Use TYPE(e) only in = / in comparisons or as a selection, never as a navigation root.
- Use TREAT(e AS SubType) to reach subclass state.
- Code-review HQL for 'type(' followed by a dot.
When it happens
Trigger: HQL such as select type(o).name from Order o or where type(o).id = 1 - the parser resolves the next path part from the discriminator node and this exception is thrown from EntityManager.createQuery(...).
Common situations: Trying to read the entity class name or discriminator column value by navigating it; assuming TYPE(e) behaves like an entity alias; porting native SQL that selects the discriminator column and dereferences it in a subquery.
Related errors
- Cannot apply TREAT operator to discriminator path
- Cannot interpret discriminator value ({discriminatorRole}) :
- Entity discriminator cannot be de-referenced
- Entity discriminator cannot be de-referenced
- NON_ENTITY_NAME
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/cfa568e255e354ac.
Report an issue: GitHub.