{"record":{"id":"57678b6326c333bf","repo":"hibernate/hibernate-orm","slug":"boolean-expression-does-not-support-min-57678b","errorCode":null,"errorMessage":"Boolean expression does not support min()","messagePattern":"Boolean expression does not support min\\(\\)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmBooleanExpressionWrapper.java","lineNumber":65,"sourceCode":"\t\treturn new SqmBooleanExpressionWrapper( nodeBuilder().nullif( this, y ) );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmBooleanExpression nullif(Boolean y) {\n\t\treturn new SqmBooleanExpressionWrapper( nodeBuilder().nullif( this, y ) );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmBooleanExpression max() {\n\t\tthrow new UnsupportedOperationException( \"Boolean expression does not support max()\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmBooleanExpression min() {\n\t\tthrow new UnsupportedOperationException( \"Boolean expression does not support min()\" );\n\t}\n\n\t@Override\n\tpublic SqmExpression<Boolean> copy(SqmCopyContext context) {\n\t\treturn wrappedExpression.copy( context );\n\t}\n\n\t@Override\n\tpublic void appendHqlString(StringBuilder hql, SqmRenderContext context) {\n\t\twrappedExpression.appendHqlString( hql, context );\n\t}\n\n\t@Override\n\tpublic <X> X accept(SemanticQueryWalker<X> walker) {\n\t\treturn wrappedExpression.accept( walker );\n\t}\n\n\t@Override","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmBooleanExpressionWrapper.java#L47-L83","documentation":"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.","triggerScenarios":"cb.wrapExpressionAsBoolean(...).min(), or .min() on SqmBooleanExpression results of nullif/coalesce over boolean paths in Hibernate 6 criteria.","commonSituations":"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.","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()."],"exampleFix":"// before\nSqmBooleanExpression flag = (SqmBooleanExpression) cb.wrapExpressionAsBoolean(root.get(\"active\"));\nquery.select(flag.min()); // UnsupportedOperationException\n// after\nquery.select(cb.max(cb.selectCase().when(cb.isTrue(root.get(\"active\")), 0).otherwise(1)));","handlingStrategy":"type-guard","validationCode":"static boolean numeric(Expression<?> e) {\n    return e.getJavaType() != null && Number.class.isAssignableFrom(e.getJavaType());\n}\n// wrapped boolean expressions: skip min(); use a case encoding instead","typeGuard":"static boolean aggregatableByMinMax(Expression<?> e) {\n    Class<?> jt = e.getJavaType();\n    return jt != null && Number.class.isAssignableFrom(jt);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["hibernate","criteria-api","aggregation","boolean","wrapper","unsupported-operation"],"backgroundTag":"min-max-on-non-numeric-type","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}