hibernate/hibernate-orm · error · IllegalQueryOperationException

Select item was of wrong entity type

Error message

Select item was of wrong entity type

What it means

Thrown as IllegalQueryOperationException when applying an org.hibernate.query.Order that is anchored to an entity class (Order.asc(Class, attributeName) / Order.by(...)) while the query's single select item is an entity root of a different, non-assignable Java type. Before sorting by 'attribute of the returned entity', SqmUtil checks order.entityClass().isAssignableFrom(root.getJavaType()); a mismatch means you asked to order the result by an attribute of an entity the query does not return.

Source

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

		return createSortSpecification( sqm, order, items, selected );
	}

	private static SqmSortSpecification createSortSpecification(
			AbstractSqmSelectQuery<?> sqm, Order<?> order, List<SqmSelectableNode<?>> items, SqmSelectableNode<?> selected) {
		final var builder = sqm.nodeBuilder();
		if ( order.entityClass() == null ) {
			// ordering by an element of the select list
			return new SqmSortSpecification(
					new SqmAliasedNodeRef( order.element(), builder.getIntegerType(), builder ),
					order.direction(), order.nullPrecedence(), !order.caseSensitive()
			);
		}
		else {
			// ordering by an attribute of the returned entity
			if ( items.size() <= 1) {
				if ( selected instanceof SqmFrom<?, ?> root ) {
					if ( !order.entityClass().isAssignableFrom( root.getJavaType() ) ) {
						throw new IllegalQueryOperationException("Select item was of wrong entity type");
					}
					final StringTokenizer tokens = new StringTokenizer( order.attributeName(), "." );
					SqmPath<?> path = root;
					while ( tokens.hasMoreTokens() ) {
						path = path.get( tokens.nextToken() );
					}
					return builder.sort( path, order.direction(), order.nullPrecedence(), !order.caseSensitive() );
				}
				else {
					throw new IllegalQueryOperationException("Select item was not an entity type");
				}
			}
			else {
				throw new IllegalQueryOperationException("Query has multiple items in the select list");
			}
		}
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Pass the entity class the query actually returns: Order.asc(Person.class, "name")
  2. Order by element position instead: Order.by(1, SortDirection.ASCENDING)
  3. Put the sort into the HQL directly: 'order by p.name'
  4. For polymorphic queries, order by an attribute declared on the queried root or its supertype

Example fix

// before
List<Person> people = session.createSelectionQuery("select p from Person p", Person.class)
        .addOrder(Order.asc(Address.class, "city"))
        .getResultList();
// after
List<Person> people = session.createSelectionQuery("select p from Person p", Person.class)
        .addOrder(Order.asc(Person.class, "name"))
        .getResultList();
Defensive patterns

Strategy: validation

Validate before calling

static <X> boolean orderAppliesToResult(Order<X> order, Class<?> resultType) {
    Class<X> entity = order.entityClass();
    return entity == null || entity.isAssignableFrom(resultType);
}

if (!orderAppliesToResult(order, Person.class)) {
    throw new IllegalArgumentException("Order entity " + order.entityClass() + " does not match query result " + Person.class);
}

Type guard

static boolean isEntityAnchoredOrderFor(Order<?> order, Class<?> selectItemType) {
    return order.entityClass() != null && order.entityClass().isAssignableFrom(selectItemType);
}

Try / catch

try {
    query.addOrder(order).getResultList();
} catch (IllegalQueryOperationException e) {
    // order spec does not fit this query: fall back to no explicit order or a safe default
    query.getResultList();
}

Prevention

When it happens

Trigger: session.createQuery("select p from Person p", Person.class).addOrder(Order.asc(Address.class, "city")); a generic DAO/grid component receives the sort entity class from the caller and it does not match the entity being queried; ordering by a completely unrelated class instead of the queried entity or its supertype.

Common situations: Reusable list endpoints where the sort specification (entity class + attribute name) arrives from the frontend or configuration; refactoring an entity while stale Order.by(OldEntity.class, ...) call sites remain; copy-pasting an order clause from another query.

Related errors


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