hibernate/hibernate-orm · error · IllegalArgumentException
selectQuery has no selection items
Error message
selectQuery has no selection items
What it means
AnonymousTupleType(SqmSelectQuery) snapshots the first QuerySpec's select clause of a CTE or from-clause subquery to derive the tuple's component names and types. An empty selection list cannot describe a tuple, so the constructor throws IllegalArgumentException('selectQuery has no selection items') while Hibernate compiles the query.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tuple/internal/AnonymousTupleType.java:66
* @author Christian Beikov
*/
@Incubating
public class AnonymousTupleType<T>
implements TupleType<T>, SqmDomainType<T>, SqmPathSource<T> {
private final JavaType<T> javaTypeDescriptor;
private final @Nullable NavigablePath[] componentSourcePaths;
private final SqmBindableType<?>[] expressibles;
private final String[] componentNames;
private final Map<String, Integer> componentIndexMap;
public AnonymousTupleType(SqmSelectQuery<T> selectQuery) {
final SqmSelectClause selectClause = selectQuery.getQueryPart()
.getFirstQuerySpec()
.getSelectClause();
if ( selectClause.getSelections().isEmpty() ) {
throw new IllegalArgumentException( "selectQuery has no selection items" );
}
// todo: right now, we "snapshot" the state of the selectQuery when creating this type, but maybe we shouldn't?
// i.e. what if the selectQuery changes later on? Or should we somehow mark the selectQuery to signal,
// that changes to the select clause are invalid after a certain point?
final List<SqmSelection<?>> selections = selectClause.getSelections();
final List<SqmSelectableNode<?>> selectableNodes = new ArrayList<>();
final List<String> aliases = new ArrayList<>();
for ( SqmSelection<?> selection : selections ) {
final boolean compound = selection.getSelectableNode().isCompoundSelection();
selection.getSelectableNode().visitSubSelectableNodes( node -> {
selectableNodes.add( node );
if ( compound ) {
aliases.add( node.getAlias() );
}
} );
if ( !compound ) {
// for compound selections we use the sub-selectable nodes aliasesView on GitHub (pinned to fad1729dce)
Solutions
- Make sure the subquery/CTE projects at least one item: call sub.select(...) (criteria) or add explicit select items (HQL) before compiling.
- Validate dynamically built queries for a non-empty select list before handing them to Hibernate.
- Log the generated HQL/SQM at query-creation time so empty select clauses are visible in tests.
Example fix
// before - subquery never selects anything
cq.subquery(Object[].class); // no select() call -> IllegalArgumentException at compile
// after - always define selections
Subquery<Object[]> sub = cq.subquery(Object[].class);
Root<Entity> e = sub.from(Entity.class);
sub.select(cb.array(e.get("id"), e.get("name"))); Defensive patterns
Strategy: validation
Validate before calling
// guard in dynamic query builders: require a selection before compiling
if (subquerySelectClauseIsEmpty(sq)) {
throw new IllegalArgumentException("CTE/subquery must project at least one item");
}
session.createQuery(hql); // only compile after the guard Try / catch
try {
return session.createQuery(hql, Object[].class).getResultList();
} catch (IllegalArgumentException e) {
// 'selectQuery has no selection items': fix query construction
throw new QueryBuildException("Generated query has an empty select list: " + hql, e);
} Prevention
- Always call select(...) on criteria subqueries immediately after from(...).
- Unit-test query builders for all branches so none can emit an empty select list.
- Log generated HQL/SQM at creation time to catch empty select clauses early.
When it happens
Trigger: Building a tuple type from an SqmSelectQuery whose first query spec has zero selections: criteria/SQM subqueries where select(...) was never called or the selection list was cleared, or HQL that ends up with an empty select clause before translation.
Common situations: Dynamic criteria/HQL string building that drops the select list under some branch; programmatic SQM construction in framework or test code; migration where implicit selection behavior changed between Hibernate versions.
Related errors
- MappedSuperclassType cannot be used to create an SqmPath - t
- LHS cannot be null for a sub-navigable reference - {}
- Not correlated
- Could not interpret attribute '%s' of basic-valued path '%s'
- Boolean expression does not support max()
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/f2749728840e7a9e.
Report an issue: GitHub.