{"record":{"id":"25f589a1fb7d831e","repo":"hibernate/hibernate-orm","slug":"cannot-apply-count-to-predicates","errorCode":null,"errorMessage":"Cannot apply `count()` to predicates","messagePattern":"Cannot apply `count\\(\\)` to predicates","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/predicate/AbstractSqmPredicate.java","lineNumber":72,"sourceCode":"\n\t@Nonnull\n\t@Override\n\tpublic BooleanOperator getOperator() {\n\t\t// most predicates are conjunctive\n\t\treturn BooleanOperator.AND;\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic List<Expression<Boolean>> getExpressions() {\n\t\t/// most predicates do not have sub-predicates\n\t\treturn new ArrayList<>(0);\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic JpaNumericExpression<Long> count() {\n\t\tthrow new UnsupportedOperationException( \"Cannot apply `count()` to predicates\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic JpaNumericExpression<Long> countDistinct() {\n\t\tthrow new UnsupportedOperationException( \"Cannot apply `countDistinct()` to predicates\" );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmBooleanExpression coalesce(@Nonnull Expression<? extends Boolean> y) {\n\t\treturn (SqmBooleanExpression) super.coalesce( y );\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic SqmBooleanExpression coalesce(Boolean y) {\n\t\treturn (SqmBooleanExpression) super.coalesce( y );","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/predicate/AbstractSqmPredicate.java#L54-L90","documentation":"AbstractSqmPredicate.count throws UnsupportedOperationException because predicates in the criteria tree are not value expressions — COUNT() is an aggregate over rows/expressions, and applying it to a boolean predicate node has no SQL meaning. Hibernate exposes count()/countDistinct() on JpaExpression, and JpaPredicate inherits the signatures, but the predicate base implementation explicitly rejects them so misuse fails at statement-build time rather than generating garbage SQL.","triggerScenarios":"Calling `predicate.count()` on any JpaPredicate/SqmPredicate — e.g. `cb.isNull( path ).count()`, or `cb.and( p1, p2 ).count()`; generic reporting code that wraps arbitrary expressions with count(); dynamic code that receives Expression<?> and calls count() without narrowing.","commonSituations":"Trying to build `SELECT COUNT(CASE WHEN ... )`-style aggregates and reaching for predicate.count() instead of cb.count/cb.sum; generic column-aggregation layers that apply count() to whatever node they hold; confusion caused by count() being visible on predicates via the interface hierarchy.","solutions":["Count rows matching the predicate: `query.select( cb.count( root ) ).where( predicate )`","For conditional aggregation use `cb.sum( cb.<Long>selectCase().when(predicate, 1L).otherwise(0L) )`","In generic code, check `!(expr instanceof JpaPredicate)` before calling count()/countDistinct()","Bind the predicate into the WHERE clause and aggregate over a real path expression"],"exampleFix":"// before\nPredicate isActive = cb.isTrue( root.get(\"active\") );\nexpr = ((JpaExpression<?>) isActive).count(); // UnsupportedOperationException\n\n// after\nquery.select( cb.count( root ) ).where( isActive );","handlingStrategy":"type-guard","validationCode":"import org.hibernate.query.criteria.JpaPredicate;\n\nif (expr instanceof JpaPredicate) {\n    throw new IllegalArgumentException(\"count() not applicable to predicates; move it to the WHERE clause\");\n}","typeGuard":"static boolean isCountable(org.hibernate.query.criteria.JpaExpression<?> e) {\n    return !(e instanceof org.hibernate.query.criteria.JpaPredicate);\n}","tryCatchPattern":null,"preventionTips":["Reach for cb.count(path) with the predicate in where() — never predicate.count()","Narrow Expression<?> nodes before calling aggregate methods","For conditional aggregates use sum(case) instead of count(predicate)"],"tags":["hibernate","criteria-api","aggregate","count","predicate","unsupported-operation"],"backgroundTag":"criteria-api-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}