hibernate/hibernate-orm · error · IllegalArgumentException
Multi-select expressions have duplicate alias '{}'
Error message
Multi-select expressions have duplicate alias '{}' What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmCriteriaNodeBuilder.java:1346
private void checkMultiselect(List<? extends Selection<?>> selections) {
final HashSet<String> aliases = new HashSet<>( determineProperSizing( selections.size() ) );
for ( var selection : selections ) {
if ( selection.isCompoundSelection() ) {
final Class<?> javaType = selection.getJavaType();
if ( javaType.isArray() ) {
throw new IllegalArgumentException(
"Selection item in a multi-select cannot contain compound array-valued elements"
);
}
if ( Tuple.class.isAssignableFrom( javaType ) ) {
throw new IllegalArgumentException(
"Selection item in a multi-select cannot contain compound tuple-valued elements"
);
}
}
final String alias = selection.getAlias();
if ( StringHelper.isNotEmpty( alias ) && !aliases.add( alias ) ) {
throw new IllegalArgumentException( "Multi-select expressions have duplicate alias '" + alias + "'" );
}
}
}
@Nonnull
@Override
public <N extends Number> SqmExpression<Double> avg(@Nonnull Expression<N> argument) {
return getFunctionDescriptor( "avg" ).generateSqmExpression(
(SqmTypedNode<?>) argument,
null,
queryEngine
);
}
@Nonnull
@Override
@SuppressWarnings("unchecked")
public <N extends Number> SqmExpression<N> sum(@Nonnull Expression<N> argument) {View on GitHub (pinned to fad1729dce)
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.
Example fix
// before
query.multiselect(e.get("id").alias("id"), m.get("id").alias("id")); // duplicate alias 'id'
// after
query.multiselect(e.get("id").alias("empId"), m.get("id").alias("mgrId")); Defensive patterns
Strategy: validation
Validate before calling
boolean aliasesUnique(List<? extends Selection<?>> items) {
Set<String> seen = new HashSet<>();
for (Selection<?> s : items) {
String a = s.getAlias();
if (a != null && !a.isEmpty() && !seen.add(a)) return false;
}
return true;
}
if (!aliasesUnique(selections)) throw new IllegalArgumentException("duplicate alias in multiselect"); Type guard
static Optional<String> firstDuplicateAlias(List<? extends Selection<?>> items) {
Set<String> seen = new HashSet<>();
return items.stream().map(Selection::getAlias)
.filter(a -> a != null && !a.isEmpty())
.filter(a -> !seen.add(a)).findFirst();
} Try / catch
try {
query.multiselect(selections);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("duplicate alias")) { /* de-duplicate: alias("empId"), alias("mgrId") */ }
else throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Selection item in a multi-select cannot contain compound arr
- Selection item in a multi-select cannot contain compound tup
- Informix does not support binary literals
- Duplicate entity definition '%s'
- Entity classes [%s] and [%s] share the entity name '%s' (ent
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/bd207caaaec5f8d9.
Report an issue: GitHub.