{"record":{"id":"f6c91f580884522d","repo":"hibernate/hibernate-orm","slug":"select-item-at-position-i-1-in-select-list-has","errorCode":null,"errorMessage":"Select item at position ${i+1} in select list has no alias (aliases are required in CTEs and in subqueries occurring in from clause)","messagePattern":"Select item at position (.+?) in select list has no alias \\(aliases are required in CTEs and in subqueries occurring in from clause\\)","errorType":"exception","errorClass":"SemanticException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/tuple/internal/AnonymousTupleType.java","lineNumber":102,"sourceCode":"\t\t\t\t// for compound selections we use the sub-selectable nodes aliases\n\t\t\t\taliases.add( selection.getAlias() );\n\t\t\t}\n\t\t}\n\n\t\texpressibles = new SqmBindableType<?>[selectableNodes.size()];\n\t\tcomponentSourcePaths = new NavigablePath[selectableNodes.size()];\n\t\tcomponentNames = new String[selectableNodes.size()];\n\t\t//noinspection unchecked\n\t\tjavaTypeDescriptor = (JavaType<T>) new ObjectArrayJavaType( getTypeDescriptors( selectableNodes ) );\n\t\tcomponentIndexMap = linkedMapOfSize( selectableNodes.size() );\n\t\tfor ( int i = 0; i < selectableNodes.size(); i++ ) {\n\t\t\texpressibles[i] = selectableNodes.get( i ).getNodeType();\n\t\t\tif ( selectableNodes.get( i ) instanceof SqmPath<?> path ) {\n\t\t\t\tcomponentSourcePaths[i] = path.getNavigablePath();\n\t\t\t}\n\t\t\tString alias = aliases.get( i );\n\t\t\tif ( alias == null ) {\n\t\t\t\tthrow new SemanticException( \"Select item at position \" + (i+1) + \" in select list has no alias\"\n\t\t\t\t\t\t+ \" (aliases are required in CTEs and in subqueries occurring in from clause)\" );\n\t\t\t}\n\t\t\tcomponentIndexMap.put( alias, i );\n\t\t\tcomponentNames[i] = alias;\n\t\t}\n\t}\n\n\tpublic AnonymousTupleType(SqmBindableType<?>[] expressibles, String[] componentNames) {\n\t\tthis.expressibles = expressibles;\n\t\tthis.componentNames = componentNames;\n\n\t\tcomponentSourcePaths = new NavigablePath[componentNames.length];\n\t\tcomponentIndexMap = linkedMapOfSize( expressibles.length );\n\t\tint elementIndex = -1;\n\t\tfor ( int i = 0; i < componentNames.length; i++ ) {\n\t\t\tif ( CollectionPart.Nature.ELEMENT.getName().equals( componentNames[i] ) ) {\n\t\t\t\telementIndex = i;\n\t\t\t}","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/tuple/internal/AnonymousTupleType.java#L84-L120","documentation":"When Hibernate 6 derives the tuple type of a CTE or a from-clause subquery, each selection must carry an alias because the tuple's components are named and looked up by alias (componentIndexMap). A select item without an alias makes the AnonymousTupleType constructor throw SemanticException('Select item at position N ... has no alias') during query compilation.","triggerScenarios":"HQL like `with cte as (select e.id, e.name from Entity e) select ... from cte` - the items e.id and e.name have no `as id` / `as name` aliases; same for from-clause subqueries used as tuple sources.","commonSituations":"Porting native SQL CTEs into HQL; migrating Hibernate 5.x applications where these query shapes were written without aliases; dynamically generated HQL that forgets aliases for some items (including compound selections like counts or case expressions).","solutions":["Alias every select item in every CTE and from-clause subquery: `select e.id as id, e.name as name from Entity e`.","Check compound selections too - every leaf selectable node needs an alias, not just the outer expression.","Add a startup/unit test that compiles all CTE queries so missing aliases fail in CI, not production."],"exampleFix":"// before\n\"with recent as (select o.id, o.date from Orders o where o.date > :d) select r.id from recent r\"\n// -> SemanticException: Select item at position 1 in select list has no alias\n\n// after\n\"with recent as (select o.id as id, o.date as date from Orders o where o.date > :d) select r.id from recent r\"","handlingStrategy":"validation","validationCode":"// validate generated HQL CTEs before execution: every select item needs an alias\nstatic String requireCteAliases(String hql) {\n    // for each CTE body, ensure select items contain \" as alias\"\n    // simplest guard: reject 'with ... as (select <expr>,' patterns lacking 'as'\n    if (CTE_ALIAS_PATTERN.matcher(hql).find()) {\n        throw new IllegalArgumentException(\"CTE select item without alias: \" + hql);\n    }\n    return hql;\n}","typeGuard":null,"tryCatchPattern":"try {\n    return session.createQuery(hql).getResultList();\n} catch (SemanticException e) {\n    // missing alias in CTE/from-subquery select list; message names the position\n    throw new QueryBuildException(\"Alias missing in CTE select list: \" + e.getMessage(), e);\n}","preventionTips":["Alias every select item in CTEs and from-clause subqueries by convention (id as id, ...).","Add a lint rule or code review checklist item for generated HQL aliases.","Compile all CTE queries in CI so missing aliases fail before production."],"tags":["hibernate","hql","cte","alias","query-translation"],"backgroundTag":"missing-select-alias","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}