{"record":{"id":"a477f166aec00223","repo":"hibernate/hibernate-orm","slug":"entity-discriminator-cannot-be-de-referenced-a477f1","errorCode":null,"errorMessage":"Entity discriminator cannot be de-referenced","messagePattern":"Entity discriminator cannot be de-referenced","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPathSource.java","lineNumber":51,"sourceCode":"\t\t\tSimpleDomainType<D> domainType,\n\t\t\tBindableType jpaBindableType) {\n\t\tsuper( localPathName, pathModel, domainType, jpaBindableType );\n\t\tthis.domainType = (BasicType<D>) domainType; // TODO: don't like this cast!\n\t}\n\n\t@Override\n\tpublic SqmPath<D> createSqmPath(SqmPath<?> lhs, @Nullable SqmPathSource<?> intermediatePathSource) {\n\t\tfinal var path = lhs.getNavigablePath();\n\t\tfinal var navigablePath =\n\t\t\t\tintermediatePathSource == null\n\t\t\t\t\t\t? path\n\t\t\t\t\t\t: path.append( intermediatePathSource.getPathName() );\n\t\treturn new AnyDiscriminatorSqmPath<>( navigablePath, pathModel, lhs, lhs.nodeBuilder() );\n\t}\n\n\t@Override\n\tpublic SqmPathSource<?> findSubPathSource(String name) {\n\t\tthrow new IllegalStateException( \"Entity discriminator cannot be de-referenced\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic PersistenceType getPersistenceType() {\n\t\treturn BASIC;\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic Class<D> getJavaType() {\n\t\treturn getExpressibleJavaType().getJavaTypeClass();\n\t}\n\n\t@Override\n\tpublic @Nullable SqmDomainType<D> getSqmType() {\n\t\treturn getPathType();\n\t}","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/model/domain/internal/AnyDiscriminatorSqmPathSource.java#L33-L69","documentation":"Same rule as the entity discriminator, but for @Any mappings: the discriminator of an ANY-valued path (AnyDiscriminatorSqmPathSource) is a scalar that names the target entity and cannot be navigated. Any attempt to resolve a sub-path source under it throws IllegalStateException from findSubPathSource.","triggerScenarios":"HQL/Criteria dereferencing the discriminator of an @Any property, e.g. order.customer.anyKeyDiscriminator.name, or generic path-expansion code calling findSubPathSource on the synthetic discriminator source of an ANY attribute. Also joining through the discriminator as if it were an association.","commonSituations":"Polymorphic @Any/@AnyDiscriminator+@AnyJoinColumn mappings (order.customer can point to any of several entity types) combined with generic query builders or GraphQL-style resolvers that expand every path. Confusing the ANY discriminator (picks the entity type) with an association you can join.","solutions":["Use the discriminator only for equality/TYPE comparisons; to access target fields, join or load the referenced entity via the ANY's key plus its discriminator-resolved entity type","In path-walking code, skip sources named \"type\"/\"class\" or instanceof AnyDiscriminatorSqmPathSource before findSubPathSource","Replace @Any with a real @ManyToOne to a shared supertype if navigable references are required"],"exampleFix":"// before (HQL)\nselect o.customer.type.name from Order o   // ANY discriminator dereference -> throws\n\n// after\nselect o.customer.name from Order o          // treat as association, or\nselect o.customer.type from Order o           // scalar compare only","handlingStrategy":"validation","validationCode":"// Skip synthetic discriminator sources when expanding @Any paths\nString name = pathSource.getPathName();\nif (\"type\".equals(name) || \"class\".equals(name)\n        || pathSource instanceof org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPathSource<?>) {\n    return; // scalar discriminator: compare only, never navigate\n}","typeGuard":"static boolean isAnyDiscriminatorSource(org.hibernate.query.sqm.tree.SqmPathSource<?> src) {\n    return src instanceof org.hibernate.metamodel.model.domain.internal.AnyDiscriminatorSqmPathSource<?>;\n}","tryCatchPattern":"try {\n    SqmPathSource<?> sub = source.findSubPathSource(name);\n} catch (IllegalStateException e) {\n    if (\"Entity discriminator cannot be de-referenced\".equals(e.getMessage())) {\n        // treat the @Any discriminator as a leaf; do not expand\n    } else throw e;\n}","preventionTips":["Model @Any discriminators as comparison-only scalars in query builders","Prefer @ManyToOne to a supertype when navigation is needed","Cover @Any attributes in path-expansion unit tests"],"tags":["hibernate","any-mapping","discriminator","hql","sqm"],"backgroundTag":"query-path-navigation-error","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}