hibernate/hibernate-orm · error · SemanticException

Could not resolve sort expression: '${sortExpression}'

Error message

Could not resolve sort expression: '${sortExpression}'

What it means

visitSortSpecification calls visitSortExpression and throws SemanticException when it returns null, i.e. the order-by expression could not be converted into any SqmExpression. This happens for order-by items that are neither resolvable expressions nor usable positional/alias references - notably bare identifiers used where positional/alias references are disallowed (inside 'over(...)' or 'within group' clauses, where allowPositionalOrAliases is false) and that also fail to resolve as paths.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java:1798

			orderByClause.addSortSpecification( visitSortSpecification(
					sortSpecificationContexts.get( i ),
					allowPositionalOrAliases
			) );
		}
		return orderByClause;
	}

	@Override
	public SqmSortSpecification visitSortSpecification(HqlParser.SortSpecificationContext ctx) {
		return visitSortSpecification( ctx, true );
	}

	private SqmSortSpecification visitSortSpecification(
			HqlParser.SortSpecificationContext ctx,
			boolean allowPositionalOrAliases) {
		final var sortExpression = visitSortExpression( ctx.sortExpression(), allowPositionalOrAliases );
		if ( sortExpression == null ) {
			throw new SemanticException( "Could not resolve sort expression: '" + ctx.sortExpression().getText() + "'",
					query );
		}
		if ( sortExpression instanceof SqmLiteral || sortExpression instanceof SqmParameter ) {
			HqlLogging.QUERY_LOGGER.debugf( "Questionable sorting by constant value: %s", sortExpression );
		}
		return new SqmSortSpecification( sortExpression, sortOrder( ctx ), nullPrecedence( ctx ) );
	}

	private static SortDirection sortOrder(HqlParser.SortSpecificationContext ctx) {
		return ctx.sortDirection() == null || ctx.sortDirection().DESC() == null
				? SortDirection.ASCENDING
				: SortDirection.DESCENDING;
	}

	private static Nulls nullPrecedence(HqlParser.SortSpecificationContext ctx) {
		if ( ctx.nullsPrecedence() == null ) {
			return Nulls.NONE;
		}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Inside over()/within group, repeat the underlying expression: 'over (order by e.name)'
  2. Verify the alias spelling against the select list
  3. Order by the actual attribute path instead of an alias

Example fix

// before
select e.name as n, rank() over (order by n) from Employee e

// after
select e.name as n, rank() over (order by e.name) from Employee e
Defensive patterns

Strategy: validation

Validate before calling

// Reject select aliases used inside over()/within group before execution
static boolean aliasInsideWindow(String hql, Set<String> selectAliases) {
    java.util.regex.Matcher m = java.util.regex.Pattern.compile("\\bover\\s*\\(([^)]*)\\)", java.util.regex.Pattern.CASE_INSENSITIVE).matcher(hql);
    while (m.find()) {
        String window = m.group(1).toLowerCase();
        for (String a : selectAliases) {
            if (java.util.regex.Pattern.compile("\\b" + java.util.regex.Pattern.quote(a.toLowerCase()) + "\\b").matcher(window).find()) return true;
        }
    }
    return false;
}

Try / catch

try {
    return em.createQuery(hql, Object[].class).getResultList();
} catch (org.hibernate.query.sqm.SemanticException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Could not resolve sort expression")) {
        throw new IllegalArgumentException("Unresolvable order-by item - spell out the expression instead of an alias: " + hql, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: 'select e.name as n, rank() over (order by n) from Employee e' (select alias inside a window ORDER BY); ordering by an identifier that is neither a select alias, a from alias, nor a resolvable attribute path.

Common situations: Using SQL-style select aliases inside window functions (accepted by several databases, rejected by HQL); alias typos; migrating JPQL between providers with different alias-scoping rules.

Related errors


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