{"record":{"id":"ce689c9b448da62f","repo":"hibernate/hibernate-orm","slug":"function-roots-can-not-be-treated","errorCode":null,"errorMessage":"Function roots can not be treated","messagePattern":"Function roots can not be treated","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmFunctionRoot.java","lineNumber":121,"sourceCode":"\tpublic String getEntityName() {\n\t\tthrow new UnsupportedOperationException( \"Function root does not have an entity type. Use getReferencedPathSource() instead.\" );\n\t}\n\n\t@Override\n\tpublic SqmPathSource<E> getResolvedModel() {\n\t\treturn getReferencedPathSource();\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic SqmCorrelatedRoot<E> createCorrelation() {\n\t\tthrow new UnsupportedOperationException();\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\tthrow new UnsupportedOperationException( \"Function roots can not be treated\" );\n\t}\n\n\t@Override\n\tpublic boolean deepEquals(SqmFrom<?, ?> object) {\n\t\treturn super.deepEquals( object )\n\t\t\t&& function.equals( ((SqmFunctionRoot<?>) object).function );\n\t}\n\n\t@Override\n\tpublic boolean isDeepCompatible(SqmFrom<?, ?> object) {\n\t\treturn super.isDeepCompatible( object )\n\t\t\t&& function.isCompatible( ((SqmFunctionRoot<?>) object).function );\n\t}\n}\n","sourceCodeStart":103,"sourceCodeEnd":136,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/domain/SqmFunctionRoot.java#L103-L136","documentation":"TREAT is defined for entity inheritance hierarchies; a SqmFunctionRoot (a root derived from a function call) does not participate in one, so treatAs throws UnsupportedOperationException. Filter predicates on the function result's columns are the supported alternative to downcasting.","triggerScenarios":"HQL 'treat(f(x) as Sub)' in the FROM clause, or criteria calling functionRoot.treatAs(SubType.class, alias, false) on a function-derived root.","commonSituations":"Applying boilerplate TREAT patterns to new function-root queries; set-returning functions that conceptually return different row kinds; porting SQL's joins over type-discriminated subqueries into HQL.","solutions":["Replace TREAT with WHERE conditions on the function result's type/kind attribute (e.g. where g.kind = 'SUB')","Move the polymorphic part to a real entity association elsewhere in the query and TREAT that instead","Restructure so the function returns a single concrete type and do subtype filtering in SQL or Java"],"exampleFix":"// before\nfrom json_rows(p.doc) g join treat(g as SpecialRow) s -- treat on function root\n\n// after\nfrom json_rows(p.doc) g where g.kind = 'SPECIAL'\n-- filter on the type/kind column; or join a real entity association and TREAT that","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean treatableRoot(SqmRoot<?> root) {\n    return !(root instanceof SqmFunctionRoot<?>);\n}","tryCatchPattern":"try {\n    SqmTreatedFrom<?, ?, ?> t = root.treatAs(target, alias, false);\n} catch (UnsupportedOperationException e) {\n    // function roots are never treatable: replace with a WHERE type/kind predicate\n    throw new IllegalStateException(\"Use a filter predicate instead of TREAT on function roots\", e);\n}","preventionTips":["Never call treatAs on function-derived roots; express subtype filtering as WHERE conditions","Route polymorphism through real entity associations joined elsewhere in the query","In generic code, skip treatAs for SqmFunctionRoot instances"],"tags":["hibernate","hql","treat","function-root","sqm"],"backgroundTag":"invalid-treat-target","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}