{"record":{"id":"e5b2912d317b42cc","repo":"hibernate/hibernate-orm","slug":"root-path-treats-can-not-be-aliased-getnavig","errorCode":null,"errorMessage":"Root path treats can not be aliased - \" + getNavigablePath().getFullPath()","messagePattern":"Root path treats can not be aliased - \" \\+ getNavigablePath\\(\\)\\.getFullPath\\(\\)","errorType":"exception","errorClass":"TreatException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmRoot.java","lineNumber":252,"sourceCode":"\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends E> SqmTreatedFrom<E,E,S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias) {\n\t\treturn treatAs( treatTarget, alias, false );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends E> SqmTreatedFrom<E,E,S> treatAs(@Nonnull Class<S> treatJavaType, @Nullable String alias, boolean fetch) {\n\t\treturn treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ), alias, fetch );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends E> SqmTreatedFrom<E,E,S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias, boolean fetch) {\n\t\tif ( alias != null ) {\n\t\t\tthrow new TreatException( \"Root path treats can not be aliased - \" + getNavigablePath().getFullPath() );\n\t\t}\n\t\tif ( fetch ) {\n\t\t\tthrow new TreatException( \"Root path treats can not be fetched - \" + getNavigablePath().getFullPath() );\n\t\t}\n\t\tfinal var treat = findTreat( treatTarget, null );\n\t\tif ( treat == null ) {\n\t\t\tfinal var treatedRoot = new SqmTreatedRoot<>( this, (SqmEntityDomainType<S>) treatTarget );\n\t\t\t@SuppressWarnings(\"unchecked\")\n\t\t\tfinal var typedTreat = (SqmTreatedFrom<E, E, S>) treatedRoot;\n\t\t\treturn addTreat( typedTreat );\n\t\t}\n\t\treturn treat;\n\t}\n\n}\n","sourceCodeStart":234,"sourceCodeEnd":268,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmRoot.java#L234-L268","documentation":"SqmRoot.treatAs(EntityDomainType, alias, fetch) throws TreatException (a Hibernate SemanticException subclass) when a non-null alias is supplied. Treating a query root means narrowing the row type (TREAT(p AS Subtype)); the treated root shares the original root's identification variable, so giving it its own alias would create two aliases for one FROM element — SQL has no syntax for that. Hibernate therefore allows root treats only without alias.","triggerScenarios":"Criteria: `root.treatAs( Sub.class, \"s\" )` or `root.treatAs( subType, \"s\", false )`. HQL equivalents like `from Person p ... where treat(p as Sub).attr = ...` with an attempted `as s` on the treat. Also generic code that always passes an alias when calling the JPA treat overloads.","commonSituations":"Copy-pasting alias patterns from joined-path treats (which do accept aliases) onto root treats; wrapper APIs that generate an alias for every treated path; migrating JPA code where users assumed treatAs(Class, String) works everywhere because the signature is on JpaFrom.","solutions":["Call the single-argument overload `root.treatAs( Sub.class )` (alias defaults to null)","Keep using the original root alias and qualify treat results through it, e.g. `select treat(p as Sub).specificAttr from Person p`","If you need an independently-aliased subtype path, join an association and treat the join instead"],"exampleFix":"// before\nJpaTreatedFrom<Person, Person, SpecialPerson> t = root.treatAs( SpecialPerson.class, \"sp\" ); // TreatException\n\n// after\nJpaTreatedFrom<Person, Person, SpecialPerson> t = root.treatAs( SpecialPerson.class );","handlingStrategy":"validation","validationCode":"import org.hibernate.query.sqm.tree.spi.from.SqmRoot;\n\nString aliasToUse = (root instanceof SqmRoot<?>) ? null : requestedAlias;\nroot.treatAs( Sub.class, aliasToUse ); // roots: always null alias","typeGuard":null,"tryCatchPattern":"try {\n    root.treatAs( Sub.class, alias );\n} catch (org.hibernate.query.sqm.tree.spi.SqmTreasureNodeExceptionIgnoreMarker e) { throw e; }\n// Prefer: catch org.hibernate.query.SemanticException at createQuery time\ntry { session.createQuery(hql).list(); }\ncatch (org.hibernate.query.SemanticException e) { /* report TreatException message */ }","preventionTips":["Root treats: always use the one-argument treatAs(Class) form","Aliased treats only on joined paths, never on roots","Wrap dynamic HQL building in unit tests that parse the query early"],"tags":["hibernate","criteria-api","hql","treat-as","alias","semantic-error"],"backgroundTag":"jpa-treat-as-unsupported","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}