hibernate/hibernate-orm · error · IllegalArgumentException
Cross join treats can not be aliased
Error message
Cross join treats can not be aliased
What it means
TREAT AS turns a join into a subtype view, and an alias on a treat creates a new identification variable. SqmCrossJoin.treatAs(EntityDomainType, alias, fetch) throws IllegalArgumentException('Cross join treats can not be aliased') when alias != null, because the underlying cross join has no identification variable to attach the treat alias to. (The Class overload delegates with alias=null, fetch=false.)
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/from/SqmCrossJoin.java:208
}
@Override
@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 );
}View on GitHub (pinned to fad1729dce)
Solutions
- Use the alias-less form - crossJoin.treatAs(Sub.class) - and reference the returned treated node directly in predicates.
- If you need an aliased treat, replace the cross join with an explicit join, which supports aliased treats.
- In generic code, pass alias=null when the join is an SqmCrossJoin.
Example fix
// before SqmTreatedCrossJoin<?, ?, Sub> t = crossJoin.treatAs( Sub.class, "sub" ); // IllegalArgumentException // after SqmTreatedCrossJoin<?, ?, Sub> t = crossJoin.treatAs( Sub.class ); cq.where( cb.equal( t.get( Sub_.code ), "X" ) );
Defensive patterns
Strategy: validation
Validate before calling
static boolean treatSupportsAlias(SqmJoin<?, ?> join) {
return !( join instanceof SqmCrossJoin );
}
// usage:
join.treatAs( Sub.class, treatSupportsAlias( join ) ? "sub" : null, false ); Prevention
- Never alias treats on cross joins - use the alias-less treatAs(Class) form.
- Branch on join type (SqmCrossJoin vs explicit join) in generic treat code.
- Prefer explicit joins when an aliased treat is required.
When it happens
Trigger: Criteria code calling crossJoin.treatAs(Sub.class, "sub") or the three-arg overload with a non-null alias; generic join-processing code that uniformly aliases every treatAs call without distinguishing join kinds.
Common situations: Reusing treatAs code written for explicit joins on a cross join; porting JPA Criteria treat() usage to Hibernate cross joins; HQL treat(...) with an alias applied to a cross-joined entity.
Related errors
- Treated cross joins doesn't support explicit alias
- Cross join treats can not be fetched
- Can't set alias on a correlated root
- Embeddable paths cannot be TREAT-ed to an entity type
- Not a treatable type: {}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/286eac06088811bc.
Report an issue: GitHub.