hibernate/hibernate-orm · error · UnsupportedOperationException
The function {name} is not an aggregate function
Error message
The function {name} is not an aggregate function What it means
Every SQM function descriptor carries a FunctionKind (NORMAL, AGGREGATE, ORDERED_SET_AGGREGATE, WINDOW). When the query requests an aggregate-shaped expression — classically a FILTER clause — the engine calls generateSqmAggregateFunctionExpression; if the descriptor's kind is not AGGREGATE it throws UnsupportedOperationException naming the function. Non-aggregate functions cannot take a FILTER clause.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/function/AbstractSqmSelfRenderingFunctionDescriptor.java:114
this,
arguments,
impliedResultType,
getArgumentsValidator(),
getReturnTypeResolver(),
queryEngine.getCriteriaBuilder(),
getName()
);
};
}
@Override
public <T> SelfRenderingSqmAggregateFunction<T> generateSqmAggregateFunctionExpression(
List<? extends SqmTypedNode<?>> arguments,
SqmPredicate filter,
ReturnableType<T> impliedResultType,
QueryEngine queryEngine) {
if ( functionKind != FunctionKind.AGGREGATE ) {
throw new UnsupportedOperationException( "The function " + getName() + " is not an aggregate function" );
}
return new SelfRenderingSqmAggregateFunction<>(
this,
this,
arguments,
filter,
impliedResultType,
getArgumentsValidator(),
getReturnTypeResolver(),
queryEngine.getCriteriaBuilder(),
getName()
);
}
@Override
public <T> SelfRenderingSqmOrderedSetAggregateFunction<T> generateSqmOrderedSetAggregateFunctionExpression(
List<? extends SqmTypedNode<?>> arguments,
SqmPredicate filter,View on GitHub (pinned to fad1729dce)
Solutions
- Use a genuine aggregate function with the FILTER clause (sum, count, avg, min, max, or a registered UDAF).
- For your own aggregate function, register the descriptor with FunctionKind.AGGREGATE (constructor argument / registerAlternateKey on a descriptor built with the aggregate kind).
- If the filter was meant as a WHERE restriction on a scalar expression, move it into the WHERE clause instead.
Example fix
// before
List<Long> r = em.createQuery("select count(p.id) filter (where p.active) from Person p", Long.class) // ok
.getResultList();
// but: 'upper(p.name) filter (where p.active)' -> UnsupportedOperationException
// after — custom aggregate registered with the right kind
queryEngine.getSqmFunctionRegistry().register(
"my_agg",
new NamedSqmFunctionDescriptor("my_agg", null, null, FunctionKind.AGGREGATE,
ArgumentRenderingStrategy.STANDARD, "my_agg(?1) filter (where ?2)")); Defensive patterns
Strategy: validation
Validate before calling
org.hibernate.query.sqm.function.SqmFunctionDescriptor f =
sessionFactory.getQueryEngine().getSqmFunctionRegistry().findFunction("my_func");
if (f == null || f.getFunctionKind() != org.hibernate.query.sqm.function.FunctionKind.AGGREGATE) {
// do not use 'my_func(...) filter (where ...)' — pick a registered aggregate or re-register with FunctionKind.AGGREGATE
} Try / catch
try { em.createQuery(ql, Long.class).getResultList(); } catch (UnsupportedOperationException e) { /* 'not an aggregate function': replace with sum/count/... or register the descriptor with FunctionKind.AGGREGATE */ throw e; } Prevention
- When registering custom functions in a dialect, always pass the correct FunctionKind explicitly.
- Reserve FILTER clauses for known aggregates; keep scalar expressions out of them.
- Cover custom dialect functions with HQL smoke tests at startup.
When it happens
Trigger: HQL or Criteria using '<nonAggregateFunc>(...) filter (where ...)' — e.g. 'select upper(p.name) filter (where p.active) from Person p'; or a custom function registered without FunctionKind.AGGREGATE (default NORMAL) then used with a filter clause. The exception is raised while building the SQM expression, i.e. at query creation/interpretation time.
Common situations: Custom dialect functions registered via NamedSqmFunctionDescriptor / SqmFunctionRegistry without passing FunctionKind.AGGREGATE, then used with FILTER; typos where an aggregate was intended (sum vs concat); expecting a UDAF wrapper to be treated as an aggregate automatically.
Related errors
- The function {name} is not an ordered set-aggregate function
- The function {name} is not a window function
- Can't emulate filter clause for inverse distribution functio
- Can't emulate filter clause for inverse distribution functio
- Entity discriminator cannot be de-referenced
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/4a7127dffa336858.
Report an issue: GitHub.