{"record":{"id":"7778eaadc90a2bea","repo":"hibernate/hibernate-orm","slug":"could-not-resolve-sort-expression-sortexpressi","errorCode":null,"errorMessage":"Could not resolve sort expression: '${sortExpression}'","messagePattern":"Could not resolve sort expression: '(.+?)'","errorType":"exception","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java","lineNumber":1798,"sourceCode":"\t\t\torderByClause.addSortSpecification( visitSortSpecification(\n\t\t\t\t\tsortSpecificationContexts.get( i ),\n\t\t\t\t\tallowPositionalOrAliases\n\t\t\t) );\n\t\t}\n\t\treturn orderByClause;\n\t}\n\n\t@Override\n\tpublic SqmSortSpecification visitSortSpecification(HqlParser.SortSpecificationContext ctx) {\n\t\treturn visitSortSpecification( ctx, true );\n\t}\n\n\tprivate SqmSortSpecification visitSortSpecification(\n\t\t\tHqlParser.SortSpecificationContext ctx,\n\t\t\tboolean allowPositionalOrAliases) {\n\t\tfinal var sortExpression = visitSortExpression( ctx.sortExpression(), allowPositionalOrAliases );\n\t\tif ( sortExpression == null ) {\n\t\t\tthrow new SemanticException( \"Could not resolve sort expression: '\" + ctx.sortExpression().getText() + \"'\",\n\t\t\t\t\tquery );\n\t\t}\n\t\tif ( sortExpression instanceof SqmLiteral || sortExpression instanceof SqmParameter ) {\n\t\t\tHqlLogging.QUERY_LOGGER.debugf( \"Questionable sorting by constant value: %s\", sortExpression );\n\t\t}\n\t\treturn new SqmSortSpecification( sortExpression, sortOrder( ctx ), nullPrecedence( ctx ) );\n\t}\n\n\tprivate static SortDirection sortOrder(HqlParser.SortSpecificationContext ctx) {\n\t\treturn ctx.sortDirection() == null || ctx.sortDirection().DESC() == null\n\t\t\t\t? SortDirection.ASCENDING\n\t\t\t\t: SortDirection.DESCENDING;\n\t}\n\n\tprivate static Nulls nullPrecedence(HqlParser.SortSpecificationContext ctx) {\n\t\tif ( ctx.nullsPrecedence() == null ) {\n\t\t\treturn Nulls.NONE;\n\t\t}","sourceCodeStart":1780,"sourceCodeEnd":1816,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java#L1780-L1816","documentation":"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.","triggerScenarios":"'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.","commonSituations":"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.","solutions":["Inside over()/within group, repeat the underlying expression: 'over (order by e.name)'","Verify the alias spelling against the select list","Order by the actual attribute path instead of an alias"],"exampleFix":"// before\nselect e.name as n, rank() over (order by n) from Employee e\n\n// after\nselect e.name as n, rank() over (order by e.name) from Employee e","handlingStrategy":"validation","validationCode":"// Reject select aliases used inside over()/within group before execution\nstatic boolean aliasInsideWindow(String hql, Set<String> selectAliases) {\n    java.util.regex.Matcher m = java.util.regex.Pattern.compile(\"\\\\bover\\\\s*\\\\(([^)]*)\\\\)\", java.util.regex.Pattern.CASE_INSENSITIVE).matcher(hql);\n    while (m.find()) {\n        String window = m.group(1).toLowerCase();\n        for (String a : selectAliases) {\n            if (java.util.regex.Pattern.compile(\"\\\\b\" + java.util.regex.Pattern.quote(a.toLowerCase()) + \"\\\\b\").matcher(window).find()) return true;\n        }\n    }\n    return false;\n}","typeGuard":null,"tryCatchPattern":"try {\n    return em.createQuery(hql, Object[].class).getResultList();\n} catch (org.hibernate.query.sqm.SemanticException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Could not resolve sort expression\")) {\n        throw new IllegalArgumentException(\"Unresolvable order-by item - spell out the expression instead of an alias: \" + hql, e);\n    }\n    throw e;\n}","preventionTips":["Never use select-list aliases inside over(...) or within group clauses - repeat the expression","Double-check alias spelling in order by against the select list","Add integration tests that translate every stored query (createQuery) so failures surface at build time"],"tags":["hql","order-by","window-function","hibernate","resolution"],"backgroundTag":"invalid-order-by-expression","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}