{"record":{"id":"cfa568e255e354ac","repo":"hibernate/hibernate-orm","slug":"discriminator-cannot-be-de-referenced","errorCode":null,"errorMessage":"Discriminator cannot be de-referenced","messagePattern":"Discriminator cannot be de-referenced","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/spi/DiscriminatorSqmPath.java","lineNumber":49,"sourceCode":"import java.util.Collection;\nimport java.util.Map;\n\n/**\n * Commonality between entity and any discriminators\n *\n * @author Steve Ebersole\n */\npublic interface DiscriminatorSqmPath<T> extends SqmPath<T> {\n\t@Override\n\tdefault void appendHqlString(StringBuilder hql, SqmRenderContext context) {\n\t\thql.append( \"type(\" );\n\t\tgetLhs().appendHqlString( hql, context );\n\t\thql.append( ')' );\n\t}\n\n\t@Override\n\tdefault SqmPath<?> resolvePathPart(String name, boolean isTerminal, SqmCreationState creationState) {\n\t\tthrow new IllegalStateException( \"Discriminator cannot be de-referenced\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tdefault <Y> SqmPath<Y> get(@Nonnull String attributeName) {\n\t\tthrow new IllegalStateException( \"Discriminator cannot be de-referenced\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tdefault <Y> SqmPath<Y> get(@Nonnull SingularAttribute<? super T, Y> attribute) {\n\t\tthrow new IllegalStateException( \"Discriminator cannot be de-referenced\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tdefault <E, C extends Collection<E>> SqmPluralPath<C, E> get(@Nonnull PluralAttribute<? super T, C, E> collection) {\n\t\tthrow new IllegalStateException( \"Discriminator cannot be de-referenced\" );","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/spi/DiscriminatorSqmPath.java#L31-L67","documentation":"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.","triggerScenarios":"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(...).","commonSituations":"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.","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."],"exampleFix":"// before\nselect o from Order o where type(o).priority = 'HIGH'\n\n// after - compare the discriminator itself, or treat to reach subclass state\nselect o from Order o where type(o) = RushOrder\nselect o from Order o where treat(o as RushOrder).priority = 'HIGH'","handlingStrategy":"type-guard","validationCode":"// reject 'type(...).' navigation before creating the query\nif (hql.matches(\"(?is).*type\\\\s*\\\\([^)]*\\\\)\\\\s*\\\\..*\")) {\n    throw new IllegalArgumentException(\"type(...) cannot be de-referenced in: \" + hql);\n}","typeGuard":"static boolean isDiscriminator(SqmPath<?> path) {\n    return path instanceof org.hibernate.query.sqm.spi.DiscriminatorSqmPath;\n}","tryCatchPattern":"try {\n    return em.createQuery(hql, Order.class).getResultList();\n} catch (IllegalStateException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"Discriminator\")) {\n        throw new IllegalArgumentException(\"type() is not navigable - compare it or use TREAT instead\", e);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["hibernate","hql","discriminator","polymorphism","path-navigation"],"backgroundTag":"discriminator-dereference","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}