hibernate/hibernate-orm · error · IllegalArgumentException
Cross join treats can not be fetched
Error message
Cross join treats can not be fetched
What it means
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).
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmCrossJoin.java:211
@Nonnull
public <S extends T> SqmTreatedCrossJoin<L, T, S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias) {
return treatAs( treatTarget, alias, false );
}
@Override
@Nonnull
public <S extends T> SqmTreatedCrossJoin<L, T, S> treatAs(@Nonnull Class<S> treatJavaType, @Nullable String alias, boolean fetch) {
return treatAs( nodeBuilder().getDomainModel().entity( treatJavaType ), alias, false );
}
@Override
@Nonnull
public <S extends T> SqmTreatedCrossJoin<L, T, S> treatAs(@Nonnull EntityDomainType<S> treatTarget, @Nullable String alias, boolean fetch) {
if ( alias != null ) {
throw new IllegalArgumentException( "Cross join treats can not be aliased" );
}
if ( fetch ) {
throw new IllegalArgumentException( "Cross join treats can not be fetched" );
}
final var treat = (SqmTreatedCrossJoin<L, T, S>) findTreat( treatTarget, null );
if ( treat == null ) {
return addTreat( new SqmTreatedCrossJoin<>( this, (SqmEntityDomainType<S>) treatTarget ) );
}
else {
return treat;
}
}
@Nonnull
@Override
public <S extends T> SqmTreatedCrossJoin<L, T, S> treatAs(@Nonnull Class<S> treatAsType) {
return treatAs( treatAsType, null, false );
}
@Nonnull
@OverrideView on GitHub (pinned to fad1729dce)
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.
Example fix
// before crossJoin.treatAs( Sub.class, null, true ); // IllegalArgumentException // after crossJoin.treatAs( Sub.class ); // fetch=false by default // fetch subtype state via an explicit fetch join instead
Defensive patterns
Strategy: validation
Validate before calling
static boolean treatSupportsFetch(SqmJoin<?, ?> join) {
return !( join instanceof SqmCrossJoin );
}
// usage:
join.treatAs( Sub.class, null, treatSupportsFetch( join ) && wantFetch ); Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Cross join treats can not be aliased
- Embeddable paths cannot be TREAT-ed to an entity type
- Not a treatable type: {}
- Cannot treat plural valued simple paths
- Treated cross joins doesn't support explicit alias
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3d4fc31bc8d89cc9.
Report an issue: GitHub.