{"record":{"id":"04284b2b9a9f51c4","repo":"hibernate/hibernate-orm","slug":"max-not-supported","errorCode":null,"errorMessage":"max() not supported","messagePattern":"max\\(\\) not supported","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmBooleanExpressionImplementor.java","lineNumber":22,"sourceCode":" */\npackage org.hibernate.query.sqm.tree.spi.expression;\n\nimport jakarta.annotation.Nonnull;\nimport jakarta.persistence.criteria.Expression;\nimport org.hibernate.query.sqm.internal.SqmCriteriaNodeBuilder;\nimport org.hibernate.query.sqm.tree.spi.predicate.SqmPredicate;\n\n/**\n * @author Steve Ebersole\n */\npublic interface SqmBooleanExpressionImplementor\n\t\textends SqmComparableExpressionImplementor<Boolean>, SqmBooleanExpression {\n\tSqmCriteriaNodeBuilder nodeBuilder();\n\n\t@Nonnull\n\t@Override\n\tdefault SqmComparableExpression<Boolean> max() {\n\t\tthrow new UnsupportedOperationException( \"max() not supported\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tdefault SqmComparableExpression<Boolean> min() {\n\t\tthrow new UnsupportedOperationException( \"min() not supported\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tdefault SqmPredicate and(@Nonnull Expression<Boolean> y) {\n\t\treturn nodeBuilder().and( this, y );\n\t}\n\n\t@Nonnull\n\t@Override\n\tdefault SqmPredicate or(@Nonnull Expression<Boolean> y) {\n\t\treturn nodeBuilder().or( this, y );","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/expression/SqmBooleanExpressionImplementor.java#L4-L40","documentation":"Hibernate's extended criteria API exposes max() directly on JpaExpression/SqmComparableExpression. Boolean expressions implement SqmBooleanExpressionImplementor, whose default max() throws UnsupportedOperationException because aggregation over Boolean is not defined in the SQM type system — there is no max Boolean basic type or comparable aggregate semantics.","triggerScenarios":"((JpaExpression<Boolean>) root.get(\"active\")).max(), booleanPath.max(), or cb.isTrue(...)-derived expressions with .max() chained in Hibernate 6 criteria code.","commonSituations":"Report queries that aggregate a boolean column ('max of active flag per group'); code migrated from native SQL where the dialect accepted max(boolean); generic aggregation helpers that call max() on whatever expression they are handed.","solutions":["Convert to numeric before aggregating: cb.sum(cb.selectCase().when(cb.isTrue(flag), 1).otherwise(0)) for 'count of trues', or max over the same case expression.","For 'any true' semantics use cb.isTrue(cb.max(...)) on the numeric projection or cb.sum(...) > 0.","Change the column mapping to a smallint/int and aggregate that, or handle the aggregation in SQL via native query where the dialect supports it.","Guard generic helpers: only call max() when the expression's Java type is numeric."],"exampleFix":"// before\nJpaExpression<Boolean> active = root.get(\"active\");\nquery.select(active.max()); // UnsupportedOperationException: max() not supported\n// after\nquery.select(cb.sum(cb.selectCase().when(cb.isTrue(root.get(\"active\")), 1).otherwise(0)));","handlingStrategy":"type-guard","validationCode":"static boolean numeric(Expression<?> e) {\n    return e.getJavaType() != null && Number.class.isAssignableFrom(e.getJavaType());\n}\n// before aggregating: if (numeric(expr)) ((JpaExpression) expr).max(); else use a case-to-int encoding","typeGuard":"static boolean aggregatableByMinMax(Expression<?> e) {\n    Class<?> jt = e.getJavaType();\n    return jt != null && Number.class.isAssignableFrom(jt)\n            && !Boolean.class.isAssignableFrom(jt);\n}","tryCatchPattern":null,"preventionTips":["Encode booleans as 0/1 with selectCase before min/max/sum aggregation.","Keep aggregation helpers type-aware: check getJavaType() before calling max()/min().","For 'any/all' flags per group, use sum(case) > 0 instead of boolean aggregates."],"tags":["hibernate","criteria-api","aggregation","boolean","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"}