hibernate/hibernate-orm · error · SemanticException

Inverse distribution function '%s' must specify 'WITHIN GROU

Error message

Inverse distribution function '%s' must specify 'WITHIN GROUP'

What it means

Inverse distribution (ordered-set aggregate) functions are defined by the SQL standard to require a WITHIN GROUP clause naming the sort expression they operate on. Hibernate's SQM representation enforces this: when the function expression is built or converted without a withinGroupClause, a SemanticException is thrown during query interpretation.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/dialect/function/InverseDistributionFunction.java:152

				List<? extends SqmTypedNode<?>> arguments,
				SqmPredicate filter,
				SqmOrderByClause withinGroupClause,
				ReturnableType<T> impliedResultType,
				QueryEngine queryEngine) {
			super(
					InverseDistributionFunction.this,
					InverseDistributionFunction.this,
					arguments,
					filter,
					withinGroupClause,
					impliedResultType,
					InverseDistributionFunction.this.getArgumentsValidator(),
					InverseDistributionFunction.this.getReturnTypeResolver(),
					queryEngine.getCriteriaBuilder(),
					InverseDistributionFunction.this.getName()
			);
			if ( withinGroupClause == null ) {
				throw new SemanticException("Inverse distribution function '" + getFunctionName()
						+ "' must specify 'WITHIN GROUP'");
			}
		}

		@Override
		protected ReturnableType<?> determineResultType(
				SqmToSqlAstConverter converter,
				TypeConfiguration typeConfiguration) {
			return (ReturnableType<?>)
					getWithinGroup().getSortSpecifications().get( 0 )
							.getSortExpression()
							.getExpressible()
							.getSqmType();
		}

		@Override
		protected MappingModelExpressible<?> getMappingModelExpressible(
				SqmToSqlAstConverter walker,

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add the required clause: percentile_cont(0.5) within group (order by t.value)
  2. For MODE use mode() within group (order by x) with exactly one order-by item
  3. Fix query-builder code that strips or never emits WITHIN GROUP

Example fix

// before
select percentile_cont(0.5) from Sale s

// after
select percentile_cont(0.5) within group (order by s.amount) from Sale s
Defensive patterns

Strategy: validation

Validate before calling

// Ordered-set aggregates require WITHIN GROUP in HQL
static void requireWithinGroup(String hql, String fn) {
    String lower = hql.toLowerCase(java.util.Locale.ROOT);
    if (lower.contains(fn.toLowerCase()) && !lower.contains("within group")) {
        throw new IllegalStateException(fn + " requires 'within group (order by ...)'");
    }
}

Try / catch

try {
    return em.createQuery(hql, Object.class).getResultList();
} catch (org.hibernate.query.SemanticException e) {
    if (e.getMessage() != null && e.getMessage().contains("WITHIN GROUP")) {
        throw new QuerySetupException("Add 'within group (order by ...)' to the ordered-set aggregate", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: HQL: select percentile_cont(0.5) from T (no 'within group (order by ...)'); the same for percentile_disc(...) or mode() called like a plain aggregate.

Common situations: Treating percentile functions like ordinary aggregates; HQL generators that omit WITHIN GROUP; copy-paste from SQL dialects where the clause is optional or has defaults.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/be03b08304cca9f7. Report an issue: GitHub.