{"record":{"id":"b395b0c1c7d0f9b9","repo":"hibernate/hibernate-orm","slug":"derived-joins-can-not-be-treated","errorCode":null,"errorMessage":"Derived joins can not be treated","messagePattern":"Derived joins can not be treated","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmDerivedJoin.java","lineNumber":198,"sourceCode":"\n\t@Override\n\tpublic <X> X accept(SemanticQueryWalker<X> walker) {\n\t\treturn walker.visitQualifiedDerivedJoin( this );\n\t}\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// JPA\n\n\t@Override\n\t@Nonnull\n\tpublic SqmCorrelatedDerivedJoin<T> createCorrelation() {\n\t\treturn new SqmCorrelatedDerivedJoin<>( this );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <S extends T> SqmTreatedJoin<T, T, S> treatAs(@Nonnull Class<S> treatTarget) {\n\t\tthrow new UnsupportedOperationException( \"Derived joins can not be treated\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <S extends T> SqmTreatedJoin<T, T, S> treatAs(@Nonnull EntityDomainType<S> treatTarget) {\n\t\tthrow new UnsupportedOperationException( \"Derived joins can not be treated\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends T> SqmTreatedJoin<T, T, S> treatAs(@Nonnull Class<S> treatJavaType, @Nullable String alias) {\n\t\tthrow new UnsupportedOperationException( \"Derived joins can not be treated\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends T> SqmTreatedJoin<T, T, S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias) {\n\t\tthrow new UnsupportedOperationException( \"Derived joins can not be treated\" );","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmDerivedJoin.java#L180-L216","documentation":"SqmDerivedJoin models a join to a subquery result: HQL `join (select ...) d on ...`, criteria `JpaFrom.join(Subquery)` / `joinLateral(...)`. The joined thing is an anonymous query result, not a metamodel entity type — SqmDerivedJoin.getAttribute() returns null — so there is no inheritance hierarchy to downcast. Every treatAs overload, including this public criteria-facing treatAs(Class<S>), throws UnsupportedOperationException at query-construction time.","triggerScenarios":"Calling treatAs(Class) on a JpaDerivedJoin: `JpaDerivedJoin<Employee> d = root.join(subquery); d.treatAs(Manager.class);` — or an HQL treat path expression over a derived-join alias such as `treat(d as Manager).salary`.","commonSituations":"Replacing an entity attribute join with a subquery join (dedup, limits, aggregates) while keeping a TREAT from the old query; generic criteria wrappers that call treatAs(Class) on arbitrary joins; Hibernate 6.x to 7 migration moving these classes to the spi.from package.","solutions":["Remove the treatAs and make the subquery select the concrete subtype (`select m from Manager m ...`) so the derived join is already correctly typed.","Join the target entity directly with an attribute/entity join (where treat is supported) and express the correlation via on/where predicates instead of joining the subquery result.","In dynamic query builders, branch on the join kind (skip treat for JpaDerivedJoin) instead of calling treatAs unconditionally."],"exampleFix":"// before - UnsupportedOperationException: Derived joins can not be treated\nJpaDerivedJoin<Employee> d = root.join( employeesSubquery );\nd.treatAs( Manager.class );\n\n// after - the subquery selects Manager, so the derived join needs no downcast\nJpaSubQuery<Manager> managerSub = query.subquery( Manager.class );\nJpaRoot<Manager> m = managerSub.from( Manager.class );\nmanagerSub.select( m ).where( cb.equal( m.get( \"department\" ), root.get( \"department\" ) ) );\nJpaDerivedJoin<Manager> d = root.join( managerSub );","handlingStrategy":"type-guard","validationCode":"import org.hibernate.query.sqm.tree.spi.from.*;\n\nif ( join instanceof SqmDerivedJoin<?> ) {\n    throw new IllegalArgumentException(\n        \"TREAT is unsupported on derived (subquery) joins; select the subtype inside the subquery\" );\n}","typeGuard":"static boolean supportsTreat(Join<?, ?> join) {\n    // derived joins are anonymous result shapes - only attribute/roots can be treated\n    return !( join instanceof SqmDerivedJoin<?> )\n        && !( join instanceof SqmCteJoin<?> )\n        && !( join instanceof SqmFunctionJoin<?> );\n}","tryCatchPattern":"try {\n    treated = ( (JpaJoin<?, ?>) join ).treatAs( Sub.class );\n} catch ( UnsupportedOperationException e ) {\n    if ( e.getMessage() != null && e.getMessage().contains( \"Derived joins\" ) ) {\n        throw new QueryConstructionException(\n            \"TREAT unsupported on derived join \" + join.getAlias()\n                + \"; type the subquery result instead\", e );\n    }\n    throw e;\n}","preventionTips":["Make subqueries select the concrete subtype so derived joins never need treat.","Reserve treatAs for attribute joins of polymorphic entities.","Branch on join kind in dynamic builders before applying treatAs(Class).","When converting an entity join to a subquery join, delete its TREAT clauses in the same change."],"tags":["hibernate","hql","jpa","criteria-api","subquery","derived-join","treat-as"],"backgroundTag":"unsupported-treat-as","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}