hibernate/hibernate-orm · error · IllegalQueryOperationException

Cannot order by element " + element + " (there are only " +

Error message

Cannot order by element " + element + " (there are only " + items + " select items)

What it means

Thrown as IllegalQueryOperationException by SqmUtil.selectedNode when Order.element() exceeds the number of selection items in the query's select clause. The order tries to sort by a select-list element that does not exist (e.g. element 3 in a two-item select list), which Hibernate detects before building the SQL order-by expression.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/internal/SqmUtil.java:968

		final int element = order.element();
		if ( element < 1) {
			throw new IllegalQueryOperationException("Cannot order by element " + element
					+ " (the first select item is element 1)");
		}
		final var querySpec = sqm.getQuerySpec();
		final var selectionItems = querySpec.getSelectClause().getSelectionItems();
		final int items = selectionItems.size();
		if ( items == 0 && element == 1 ) {
			if ( order.entityClass() == null || querySpec.getRootList().size() > 1 ) {
				throw new IllegalQueryOperationException("Cannot order by element " + element
						+ " (there is no select list)");
			}
			else {
				return querySpec.getRootList().get(0);
			}
		}
		else if ( element > items ) {
			throw new IllegalQueryOperationException( "Cannot order by element " + element
					+ " (there are only " + items + " select items)");
		}
		else {
			return selectionItems.get( element - 1 );
		}
	}

	public static boolean isSelectionAssignableToResultType(SqmSelection<?> selection, Class<?> expectedResultType) {
		if ( expectedResultType == null ) {
			return true;
		}
		else if ( selection != null && selection.getSelectableNode() instanceof SqmParameter<?> sqmParameter ) {
			final BindableType<?> anticipatedType = sqmParameter.getAnticipatedType();
			final var anticipatedClass = anticipatedType != null ? anticipatedType.getJavaType() : null;
			return anticipatedClass != null && expectedResultType.isAssignableFrom( anticipatedClass );
		}
		else if ( selection == null
				|| !isHqlTuple( selection ) && selection.getSelectableNode().isCompoundSelection() ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Clamp or validate the element index against the actual select-list size before addOrder
  2. Update the order to an existing element or to an entity-anchored Order.asc(Class, attribute)
  3. Map UI column indexes to explicit HQL order-by paths instead of raw positions
  4. Add the missing select item if the order intentionally references it

Example fix

// before (query selects 2 items, order asks for element 3)
query.addOrder(Order.by(3, SortDirection.ASCENDING));
// after
if (orderIndex >= 1 && orderIndex <= selectItemCount) {
    query.addOrder(Order.by(orderIndex, SortDirection.ASCENDING));
}
Defensive patterns

Strategy: validation

Validate before calling

static Order<?> clampOrValidate(Order<?> order, int selectItemCount) {
    int element = order.element();
    if (order.entityClass() == null && (element < 1 || element > selectItemCount)) {
        throw new IllegalArgumentException(
            "Sort element " + element + " outside select list of " + selectItemCount + " items");
    }
    return order;
}
// call clampOrValidate(order, selectItemCount) before query.addOrder(order)

Try / catch

try {
    query.addOrder(order).getResultList();
} catch (IllegalQueryOperationException e) {
    // element out of range: degrade to default deterministic ordering
    query.addOrder(Order.by(1, SortDirection.ASCENDING)).getResultList();
}

Prevention

When it happens

Trigger: Order.by(3, direction) on 'select p.name, p.age from Person p'; a sort-column index computed from an external spec while the query was later changed to fewer select items; ordering by element 2 on a single-item projection; count queries (one item) receiving an order built for a wider list query.

Common situations: Shared order objects reused across queries whose select lists differ in width; refactoring a projection from three columns to two while the UI still sends column index 3; DataTables-style grid sorting where the visible column list and the query's select list drift apart.

Related errors


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