hibernate/hibernate-orm · error · UnsupportedOperationException
Boolean expression does not support max()
Error message
Boolean expression does not support max()
What it means
SqmBooleanExpressionWrapper adapts an arbitrary SQM expression to the Boolean expression API (e.g. results of nodeBuilder().wrapExpressionAsBoolean or boolean-producing operations). Its max() throws UnsupportedOperationException('Boolean expression does not support max()') because Boolean aggregation is not representable in the SQM type system.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmBooleanExpressionWrapper.java:59
return new SqmBooleanExpressionWrapper( nodeBuilder().coalesce( this, y ) );
}
@Nonnull
@Override
public SqmBooleanExpression nullif(@Nonnull Expression<? extends Boolean> y) {
return new SqmBooleanExpressionWrapper( nodeBuilder().nullif( this, y ) );
}
@Nonnull
@Override
public SqmBooleanExpression nullif(Boolean y) {
return new SqmBooleanExpressionWrapper( nodeBuilder().nullif( this, y ) );
}
@Nonnull
@Override
public SqmBooleanExpression max() {
throw new UnsupportedOperationException( "Boolean expression does not support max()" );
}
@Nonnull
@Override
public SqmBooleanExpression min() {
throw new UnsupportedOperationException( "Boolean expression does not support min()" );
}
@Override
public SqmExpression<Boolean> copy(SqmCopyContext context) {
return wrappedExpression.copy( context );
}
@Override
public void appendHqlString(StringBuilder hql, SqmRenderContext context) {
wrappedExpression.appendHqlString( hql, context );
}
View on GitHub (pinned to fad1729dce)
Solutions
- Aggregate a numeric encoding instead: wrap the aggregate, not the boolean — cb.max(cb.selectCase().when(cb.isTrue(wrapped), 1).otherwise(0)).
- Use cb.sum over the case encoding when you need a count of true values.
- Perform the rollup in native SQL if the dialect supports boolean aggregates.
- Keep a type check in generic aggregation code: skip max()/min() for Boolean-typed expressions.
Example fix
// before
SqmBooleanExpression flag = (SqmBooleanExpression) cb.wrapExpressionAsBoolean(root.get("active"));
query.select(flag.max()); // UnsupportedOperationException
// after
query.select(cb.sum(cb.selectCase().when(cb.isTrue(root.get("active")), 1).otherwise(0))); Defensive patterns
Strategy: type-guard
Validate before calling
static boolean numeric(Expression<?> e) {
return e.getJavaType() != null && Number.class.isAssignableFrom(e.getJavaType());
}
// wrapped boolean expressions: skip max(); aggregate a case-to-int projection instead Type guard
static boolean aggregatableByMinMax(Expression<?> e) {
Class<?> jt = e.getJavaType();
return jt != null && Number.class.isAssignableFrom(jt);
} Prevention
- Do not wrap-then-aggregate booleans; build the numeric projection first, then wrap if needed.
- Centralize aggregation behind one helper that checks expression Java type.
- Cover boolean rollup queries with tests against H2/embedded DB to catch them early.
When it happens
Trigger: Calling .max() on an expression wrapped into the Boolean API: cb.wrapExpressionAsBoolean(expr).max(), or operations that return SqmBooleanExpression (nullif/Coalesce over booleans) followed by .max().
Common situations: Fluent criteria pipelines that wrap then aggregate; aggregation helpers receiving already-wrapped boolean expressions; queries generating per-group boolean rollups.
Related errors
- Boolean expression does not support min()
- max() not supported
- min() not supported
- DELETE query cannot be sub-query
- Boolean expression does not support max()
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/e89a7500c61bd1a1.
Report an issue: GitHub.