{"record":{"id":"bd207caaaec5f8d9","repo":"hibernate/hibernate-orm","slug":"multi-select-expressions-have-duplicate-alias","errorCode":null,"errorMessage":"Multi-select expressions have duplicate alias '{}'","messagePattern":"Multi-select expressions have duplicate alias '(.+?)'","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java","lineNumber":1346,"sourceCode":"\tprivate void checkMultiselect(List<? extends Selection<?>> selections) {\n\t\tfinal HashSet<String> aliases = new HashSet<>( determineProperSizing( selections.size() ) );\n\t\tfor ( var selection : selections ) {\n\t\t\tif ( selection.isCompoundSelection() ) {\n\t\t\t\tfinal Class<?> javaType = selection.getJavaType();\n\t\t\t\tif ( javaType.isArray() ) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Selection item in a multi-select cannot contain compound array-valued elements\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif ( Tuple.class.isAssignableFrom( javaType ) ) {\n\t\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\t\"Selection item in a multi-select cannot contain compound tuple-valued elements\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfinal String alias = selection.getAlias();\n\t\t\tif ( StringHelper.isNotEmpty( alias ) && !aliases.add( alias ) ) {\n\t\t\t\tthrow new IllegalArgumentException( \"Multi-select expressions have duplicate alias '\" + alias + \"'\" );\n\t\t\t}\n\t\t}\n\t}\n\n\t@Nonnull\n\t@Override\n\tpublic <N extends Number> SqmExpression<Double> avg(@Nonnull Expression<N> argument) {\n\t\treturn getFunctionDescriptor( \"avg\" ).generateSqmExpression(\n\t\t\t\t(SqmTypedNode<?>) argument,\n\t\t\t\tnull,\n\t\t\t\tqueryEngine\n\t\t);\n\t}\n\n\t@Nonnull\n\t@Override\n\t@SuppressWarnings(\"unchecked\")\n\tpublic <N extends Number> SqmExpression<N> sum(@Nonnull Expression<N> argument) {","sourceCodeStart":1328,"sourceCodeEnd":1364,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java#L1328-L1364","documentation":"checkMultiselect also enforces alias uniqueness: among the selection items passed to multiselect, any non-empty alias (selection.alias(...)) may occur at most once. A repeated alias would make result-by-name mapping ambiguous, so Hibernate throws IllegalArgumentException naming the duplicated alias.","triggerScenarios":"query.multiselect(root.get(\"id\").alias(\"id\"), otherRoot.get(\"id\").alias(\"id\")); self-joins where both sides expose the same attribute alias; dynamic projections assembled from column catalogs that reuse display names ('name', 'value'); expressions that inherit an alias from a reused Selection instance.","commonSituations":"Generic grid/report builders that map UI column keys straight to aliases and collide on joins; entity self-joins (employee/manager both aliasing 'name'); copy-pasted selection lists where one alias is forgotten to be renamed.","solutions":["Give every aliased item a unique alias (id1/id2, empName/mgrName).","If aliases are generated from a column catalog, de-duplicate by appending an index or the path prefix.","Drop aliases on items that don't need name-based access."],"exampleFix":"// before\nquery.multiselect(e.get(\"id\").alias(\"id\"), m.get(\"id\").alias(\"id\")); // duplicate alias 'id'\n\n// after\nquery.multiselect(e.get(\"id\").alias(\"empId\"), m.get(\"id\").alias(\"mgrId\"));","handlingStrategy":"validation","validationCode":"boolean aliasesUnique(List<? extends Selection<?>> items) {\n    Set<String> seen = new HashSet<>();\n    for (Selection<?> s : items) {\n        String a = s.getAlias();\n        if (a != null && !a.isEmpty() && !seen.add(a)) return false;\n    }\n    return true;\n}\nif (!aliasesUnique(selections)) throw new IllegalArgumentException(\"duplicate alias in multiselect\");","typeGuard":"static Optional<String> firstDuplicateAlias(List<? extends Selection<?>> items) {\n    Set<String> seen = new HashSet<>();\n    return items.stream().map(Selection::getAlias)\n            .filter(a -> a != null && !a.isEmpty())\n            .filter(a -> !seen.add(a)).findFirst();\n}","tryCatchPattern":"try {\n    query.multiselect(selections);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"duplicate alias\")) { /* de-duplicate: alias(\"empId\"), alias(\"mgrId\") */ }\n    else throw e;\n}","preventionTips":["Generate aliases from a de-duplicated column catalog (append path prefix or index on collision).","In self-joins, prefix aliases with the join alias (e_, m_).","Validate alias uniqueness once in your query-builder layer instead of relying on Hibernate at query build time."],"tags":["hibernate","criteria","multiselect","alias","duplicate"],"backgroundTag":"duplicate-select-alias","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}