{"record":{"id":"fd1b19b8de5b0109","repo":"hibernate/hibernate-orm","slug":"function-joins-can-not-be-treated","errorCode":null,"errorMessage":"Function joins can not be treated","messagePattern":"Function 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/SqmFunctionJoin.java","lineNumber":192,"sourceCode":"\t@Override\n\tpublic <X> X accept(SemanticQueryWalker<X> walker) {\n\t\treturn walker.visitQualifiedFunctionJoin( this );\n\t}\n\n\n\t// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\t// JPA\n\n\t@Override\n\t@Nonnull\n\tpublic SqmCorrelation<Object, E> createCorrelation() {\n\t\tthrow new UnsupportedOperationException();\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <S extends E> SqmTreatedJoin<Object, E, S> treatAs(@Nonnull Class<S> treatTarget) {\n\t\tthrow new UnsupportedOperationException( \"Function joins can not be treated\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <S extends E> SqmTreatedJoin<Object, E, S> treatAs(@Nonnull EntityDomainType<S> treatTarget) {\n\t\tthrow new UnsupportedOperationException( \"Function joins can not be treated\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends E> SqmTreatedJoin<Object, E, S> treatAs(@Nonnull Class<S> treatJavaType, @Nullable String alias) {\n\t\tthrow new UnsupportedOperationException( \"Function joins can not be treated\" );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends E> SqmTreatedJoin<Object, E, S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias) {\n\t\tthrow new UnsupportedOperationException( \"Function joins can not be treated\" );","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmFunctionJoin.java#L174-L210","documentation":"SqmFunctionJoin models a join to the result of a set-returning function (`join unnest(...)`, `join generate_series(...)`, criteria JpaFrom.join(JpaSetReturningFunction)). The joined tuple is function output, not a persistent entity with an inheritance hierarchy — even createCorrelation() is unimplemented in this class. Consequently every treatAs overload, including this public criteria-facing treatAs(Class<S>), throws UnsupportedOperationException the moment it is called during query construction.","triggerScenarios":"Calling treatAs(Class) on a JpaFunctionJoin: `JpaFunctionJoin<Long> g = root.join(cb.generateSeries(1, 10)); g.treatAs(MyEntity.class);`, or an HQL treat expression over a function-join alias (`treat(i as SubType)` where i comes from `join unnest(:ids) i`).","commonSituations":"Unnesting arrays/collections of entity ids and trying to downcast the unnest result directly; generic criteria wrappers calling treatAs(Class) on any join; adopting Hibernate 7 set-returning functions in queries that previously joined entity collections with TREAT.","solutions":["Remove the treat on the function join: project the key from the function output and join the entity separately (`join unnest(:ids) i join Employee e on e.id = i.value`), then treat that entity join.","Consume the function output as its declared element type; a downcast to an entity subtype is never valid on function output.","If entity-typed rows are needed, wrap the function in a subquery that selects entities and join the derived result instead."],"exampleFix":"-- before: treat on a function join -> Function joins can not be treated\nselect treat(u as Manager).salary from Client c join unnest(c.managerIds) u\n\n-- after: unnest yields ids; join and treat the entity side instead\nselect treat(e as Manager).salary\nfrom Client c join unnest(c.managerIds) i join Employee e on e.id = i.value","handlingStrategy":"type-guard","validationCode":"import org.hibernate.query.sqm.tree.spi.from.*;\n\nif ( join instanceof SqmFunctionJoin<?> ) {\n    throw new IllegalArgumentException(\n        \"TREAT is unsupported on function joins; join the entity separately and treat that join\" );\n}","typeGuard":"static boolean supportsTreat(Join<?, ?> join) {\n    return !( join instanceof SqmFunctionJoin<?> )\n        && !( join instanceof SqmDerivedJoin<?> )\n        && !( join instanceof SqmCteJoin<?> );\n}","tryCatchPattern":"try {\n    treated = ( (JpaJoin<?, ?>) join ).treatAs( Sub.class );\n} catch ( UnsupportedOperationException e ) {\n    if ( e.getMessage() != null && e.getMessage().startsWith( \"Function joins\" ) ) {\n        throw new QueryConstructionException(\n            \"TREAT unsupported on function join \" + join.getAlias()\n                + \"; project ids from the function and join the entity\", e );\n    }\n    throw e;\n}","preventionTips":["Treat joins model an entity; function output is scalar — keep them separate.","Pattern: unnest ids, then join the entity on that id, then treat the entity join.","Branch on join kind in generic treat helpers before calling treatAs(Class).","Add function joins to the fixture set of any query-DSL layer that applies treats."],"tags":["hibernate","hql","jpa","criteria-api","set-returning-function","unnest","treat-as"],"backgroundTag":"unsupported-treat-as","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}