hibernate/hibernate-orm · error · IllegalSelectQueryException
Expecting a selection query, but found '{}'
Error message
Expecting a selection query, but found '{}' What it means
Selection-query APIs (createSelectionQuery and typed/named variants) pass through checkSelectionQuery(): the interpreted SQM statement must be an SqmSelectStatement. An UPDATE/DELETE/INSERT string yields IllegalSelectQueryException('Expecting a selection query, but found <hql>'). Like error 1553, this guards the selection/mutation API split so result-list semantics are guaranteed.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java:2075
return getMappingMetamodel().getEntityDescriptor( entityName );
}
// Hibernate Reactive may need to use this
protected final CollectionPersister requireCollectionPersister(String roleName) {
return getMappingMetamodel().getCollectionDescriptor( roleName );
}
protected HqlInterpretation<?> interpretHql(String hql) {
return interpretHql( hql, null );
}
protected <R> HqlInterpretation<R> interpretHql(String hql, Class<R> resultType) {
return getFactory().getQueryEngine().interpretHql( hql, resultType );
}
protected static void checkSelectionQuery(String hql, HqlInterpretation<?> hqlInterpretation) {
if ( !( hqlInterpretation.getSqmStatement() instanceof SqmSelectStatement ) ) {
throw new IllegalSelectQueryException( "Expecting a selection query, but found '" + hql + "'", hql);
}
}
protected static <R> void checkResultType(Class<R> expectedResultType, SelectionQuery<R> query) {
final var resultType = query.getResultType();
if ( !expectedResultType.isAssignableFrom( resultType ) ) {
throw new QueryTypeMismatchException(
String.format(
Locale.ROOT,
"Incorrect query result type: query produces '%s' but type '%s' was given",
expectedResultType.getName(),
resultType.getName()
)
);
}
}
protected NamedResultSetMappingMemento getResultSetMappingMemento(String resultSetMappingName) {View on GitHub (pinned to fad1729dce)
Solutions
- Route DML to createMutationQuery/executeUpdate; use createSelectionQuery only for SELECT.
- Fix the HQL when a select was intended but the statement parses as DML.
- For named queries, match the creation API to the kind declared in @NamedQuery.
Example fix
// before
SelectionQuery<?> q = session.createSelectionQuery("update Account a set a.locked = true"); // throws
// after
MutationQuery q = session.createMutationQuery("update Account a set a.locked = true");
q.executeUpdate(); Defensive patterns
Strategy: type-guard
Type guard
static boolean isSelectHql(String hql) {
String head = hql.stripLeading().toLowerCase(Locale.ROOT);
return !(head.startsWith("update ") || head.startsWith("delete ") || head.startsWith("insert "));
}
// usage
if (isSelectHql(hql)) {
results = session.createSelectionQuery(hql, type).list();
} else {
session.createMutationQuery(hql).executeUpdate();
} Try / catch
try {
return session.createSelectionQuery(hql, type).list();
} catch (IllegalSelectQueryException e) {
throw new IllegalArgumentException("Expected SELECT but got: " + hql, e);
} Prevention
- Pick the creation API by statement kind, not convenience
- Keep dynamically-built HQL builders honest about which kind they emit
- Align @NamedQuery definitions with the API used to load them
When it happens
Trigger: session.createSelectionQuery("update Account a set a.locked = true"); createSelectionQuery(hql, type) with DML; createNamedQuery(name, type) where the named query is defined as an update/delete; generic helpers funneling all strings into selection creation.
Common situations: Shared DAO query methods that build HQL dynamically and pick the wrong factory; porting Hibernate 5 code where Query served both roles; a malformed select that parses as DML (missing 'from' or a stray 'update' keyword).
Related errors
- Query string is not a mutation
- Could not resolve attribute '%s' of '%s' due to the attribut
- Expecting a restricted mutation query [%s], but found %s
- Select item was of wrong entity type
- Domain result for non-scalar subquery shouldn't be created
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/f6f41411eecf41dd.
Report an issue: GitHub.