hibernate/hibernate-orm · error · UnsupportedOperationException
Boolean expression does not support min()
Error message
Boolean expression does not support min()
What it means
SqmBooleanExpressionWrapper.min() mirrors max(): Boolean-typed wrapped expressions cannot be minimized in SQM because there is no Boolean min aggregate semantics, so Hibernate throws UnsupportedOperationException('Boolean expression does not support min()') as soon as the criteria tree is built.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmBooleanExpressionWrapper.java:65
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 );
}
@Override
public <X> X accept(SemanticQueryWalker<X> walker) {
return wrappedExpression.accept( walker );
}
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Re-express as numeric: cb.max(cb.selectCase().when(cb.isTrue(flag), 0).otherwise(1)) yields the 'min boolean' information in numeric form.
- Use cb.sum(...) to count true rows per group instead of min/max.
- Aggregate at the SQL level via native query where the dialect supports boolean min/max.
- Guard aggregation helpers with a numeric type check before calling min().
Example fix
// before
SqmBooleanExpression flag = (SqmBooleanExpression) cb.wrapExpressionAsBoolean(root.get("active"));
query.select(flag.min()); // UnsupportedOperationException
// after
query.select(cb.max(cb.selectCase().when(cb.isTrue(root.get("active")), 0).otherwise(1))); 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 min(); use a case encoding instead Type guard
static boolean aggregatableByMinMax(Expression<?> e) {
Class<?> jt = e.getJavaType();
return jt != null && Number.class.isAssignableFrom(jt);
} Prevention
- Aggregate numeric encodings of flags; never boolean expressions.
- Type-check in shared criteria utilities before chaining min()/max().
- Document per-dialect boolean aggregate support and use native SQL where needed.
When it happens
Trigger: cb.wrapExpressionAsBoolean(...).min(), or .min() on SqmBooleanExpression results of nullif/coalesce over boolean paths in Hibernate 6 criteria.
Common situations: Report queries rolling up boolean flags; fluent builders that wrap boolean expressions then chain aggregates; codebases moving from HQL string min(boolean) attempts to typed criteria.
Related errors
- Boolean expression does not support max()
- 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/57678b6326c333bf.
Report an issue: GitHub.