{"record":{"id":"3d4fc31bc8d89cc9","repo":"hibernate/hibernate-orm","slug":"cross-join-treats-can-not-be-fetched","errorCode":null,"errorMessage":"Cross join treats can not be fetched","messagePattern":"Cross join treats can not be fetched","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmCrossJoin.java","lineNumber":211,"sourceCode":"\t@Nonnull\n\tpublic <S extends T> SqmTreatedCrossJoin<L, T, 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 T> SqmTreatedCrossJoin<L, T, S> treatAs(@Nonnull Class<S> treatJavaType, @Nullable String alias, boolean fetch) {\n\t\treturn treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ), alias, false );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic <S extends T> SqmTreatedCrossJoin<L, T, S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias, boolean fetch) {\n\t\tif ( alias != null ) {\n\t\t\tthrow new IllegalArgumentException( \"Cross join treats can not be aliased\" );\n\t\t}\n\t\tif ( fetch ) {\n\t\t\tthrow new IllegalArgumentException( \"Cross join treats can not be fetched\" );\n\t\t}\n\t\tfinal var treat = (SqmTreatedCrossJoin<L, T, S>) findTreat( treatTarget, null );\n\t\tif ( treat == null ) {\n\t\t\treturn addTreat( new SqmTreatedCrossJoin<>( this, (SqmEntityDomainType<S>) treatTarget ) );\n\t\t}\n\t\telse {\n\t\t\treturn treat;\n\t\t}\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <S extends T> SqmTreatedCrossJoin<L, T, S> treatAs(@Nonnull Class<S> treatAsType) {\n\t\treturn treatAs( treatAsType, null, false );\n\t}\n\n\t@Nonnull\n\t@Override","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmCrossJoin.java#L193-L229","documentation":"Fetching through a treat is only meaningful for association fetches. SqmCrossJoin.treatAs(..., alias, fetch) throws IllegalArgumentException('Cross join treats can not be fetched') when fetch=true - a cross join is not a fetch point, so Hibernate rejects the request outright (and the Class convenience overload always passes fetch=false).","triggerScenarios":"Calling crossJoin.treatAs(Sub.class, null, true) or any convenience overload that requests fetch: generic fetch-treat helpers applied to all joins, or code that always passes fetch=true to avoid lazy subtype state.","commonSituations":"Generic treat/fetch utilities that do not branch on join type; porting fetch-treat usage from explicit joins to cross joins; performance tuning that blindly fetches through treats.","solutions":["Call the fetch-less overload: crossJoin.treatAs(Sub.class).","Add a real fetch join for the subtype attribute you need instead of fetching through a cross-join treat.","In generic code, force fetch=false when the join is an SqmCrossJoin."],"exampleFix":"// before\ncrossJoin.treatAs( Sub.class, null, true ); // IllegalArgumentException\n\n// after\ncrossJoin.treatAs( Sub.class );             // fetch=false by default\n// fetch subtype state via an explicit fetch join instead","handlingStrategy":"validation","validationCode":"static boolean treatSupportsFetch(SqmJoin<?, ?> join) {\n    return !( join instanceof SqmCrossJoin );\n}\n// usage:\njoin.treatAs( Sub.class, null, treatSupportsFetch( join ) && wantFetch );","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never request fetch through a treat on a cross join.","Fetch subtype state with an explicit fetch join instead.","Force fetch=false for SqmCrossJoin in generic treat/fetch helpers."],"tags":["hibernate","sqm","cross-join","treat","fetch","criteria-api"],"backgroundTag":"unsupported-treat-operation","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}