hibernate/hibernate-orm · error · IllegalStateException
Multiple from elements expose unqualified attribute: ${ident
Error message
Multiple from elements expose unqualified attribute: ${identifierText} What it means
Thrown while resolving an unqualified identifier in group-by/order-by against the select list: the identifier names a sub-path source exposed by a select item that is an SqmFrom, and a second from-element select item exposes the same attribute name. The first match records sqmPosition; the second match finds sqmPosition != 0 and throws IllegalStateException because the positional reference would be ambiguous.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/hql/internal/SemanticQueryBuilder.java:1666
// If the current query part is a query group, check if the text matches
// an attribute name of one of the selected SqmFrom elements or the path source name of a SqmPath
SqmFrom<?, ?> found = null;
int sqmPosition = 0;
final var selections = queryPart.getFirstQuerySpec().getSelectClause().getSelections();
for ( int i = 0; i < selections.size(); i++ ) {
final var sqmSelection = selections.get( i );
if ( identifierText.equals( sqmSelection.getAlias() ) ) {
return new SqmAliasedNodeRef(
i + 1,
nodeBuilder.getIntegerType(),
nodeBuilder
);
}
final var selectableNode = sqmSelection.getSelectableNode();
if ( selectableNode instanceof SqmFrom<?, ?> fromElement ) {
if ( fromElement.getReferencedPathSource().findSubPathSource( identifierText ) != null ) {
if ( sqmPosition != 0 ) {
throw new IllegalStateException(
"Multiple from elements expose unqualified attribute: " + identifierText );
}
found = fromElement;
sqmPosition = i + 1;
}
}
else if ( selectableNode instanceof SqmPath<?> path ) {
if ( identifierText.equals( path.getReferencedPathSource().getPathName() ) ) {
if ( sqmPosition != 0 ) {
throw new IllegalStateException(
"Multiple from elements expose unqualified attribute: " + identifierText );
}
sqmPosition = i + 1;
}
}
}
if ( found != null ) {
return new SqmAliasedNodeRef(View on GitHub (pinned to fad1729dce)
Solutions
- Qualify the identifier with the from-alias: 'group by e.name'
- Give the select expression an alias and group by that alias
- Restructure the select list so only one candidate from-element exposes the attribute
Example fix
// before select e, d from Employee e join e.department d group by name // after select e, d from Employee e join e.department d group by e.name
Defensive patterns
Strategy: validation
Validate before calling
static boolean uniqueAttributeExposure(EntityManagerFactory emf, String hqlEntity, String attr, List<String> otherAliases) {
// conservative check: ensure the unqualified attribute exists on exactly one from-element type
var metamodel = emf.getMetamodel();
long matches = otherAliases.stream().filter(a -> {
try {
var attrFound = metamodel.entity(a).getAttribute(attr) != null;
return attrFound;
} catch (IllegalArgumentException unknown) {
return false;
}
}).count();
return matches <= 1;
} Try / catch
try {
return session.createQuery(hql, Object[].class).list();
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Multiple from elements expose unqualified attribute")) {
throw new IllegalArgumentException("Ambiguous group-by attribute - qualify it with an alias: " + hql, e);
}
throw e;
} Prevention
- Always qualify group-by/order-by attributes with their from-alias ('group by e.name')
- Alias every select item so grouping can target unambiguous aliases
- Watch for common attribute names (id, name, version) when joining multiple roots
When it happens
Trigger: 'select e, d from Employee e join Department d ... group by name' where both e and d expose an attribute 'name'; any unqualified group-by identifier resolvable through two or more from-elements appearing in the select list.
Common situations: Entities sharing attribute names (id, name, version, code); queries selecting multiple roots or joins and grouping by a bare column name; refactors that add a second from-element with a colliding attribute name.
Related errors
- Summarization is not supported by DBMS
- Summarization is not supported by DBMS
- Summarization is not supported by DBMS
- Summarization is not supported by DBMS
- Summarization is not supported by DBMS
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/bbd580f192e6c00b.
Report an issue: GitHub.