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 aliases

View on GitHub (pinned to fad1729dce)

Solutions

  1. Make sure the subquery/CTE projects at least one item: call sub.select(...) (criteria) or add explicit select items (HQL) before compiling.
  2. Validate dynamically built queries for a non-empty select list before handing them to Hibernate.
  3. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/f2749728840e7a9e. Report an issue: GitHub.