hibernate/hibernate-orm · error · IllegalArgumentException
No assignments specified as part of UPDATE criteria
Error message
No assignments specified as part of UPDATE criteria
What it means
Before an UPDATE statement is executed, SqmUpdateStatement.validate() checks the SET clause contains at least one assignment. A criteria update built with cb.createCriteriaUpdate(...) but without any set(...) call has nothing to update, and Hibernate throws IllegalArgumentException. HQL updates always carry assignments syntactically, so this error is essentially criteria-only.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/update/SqmUpdateStatement.java:156
new SqmUpdateStatement<>(
nodeBuilder(),
newQuerySource == null ? getQuerySource() : newQuerySource,
copyParameters( context ),
copyCteStatements( context ),
getTarget().copy( context ),
versioned
)
);
statement.setWhereClause( copyWhereClause( context ) );
statement.setClause = setClause.copy( context );
return statement;
}
@Override
public void validate(@Nullable String hql) {
verifyImmutableEntityUpdate( hql );
if ( getSetClause().getAssignments().isEmpty() ) {
throw new IllegalArgumentException( "No assignments specified as part of UPDATE criteria" );
}
if ( getQuerySource() == SqmQuerySource.CRITERIA ) {
SqmUtil.validateCriteriaTree( this );
}
verifyUpdateTypesMatch();
}
private void verifyImmutableEntityUpdate(@Nullable String hql) {
final EntityPersister persister =
nodeBuilder().getMappingMetamodel().getEntityDescriptor( getTarget().getEntityName() );
if ( !persister.isMutable() ) {
final String querySpaces = Arrays.toString( persister.getQuerySpaces() );
switch ( nodeBuilder().getImmutableEntityUpdateQueryHandlingMode() ) {
case ALLOW :
CORE_LOGGER.immutableEntityUpdateQueryAllowed( hql, querySpaces );
break;
case WARNING:
CORE_LOGGER.immutableEntityUpdateQuery( hql, querySpaces );View on GitHub (pinned to fad1729dce)
Solutions
- Add at least one set(...) before creating/executing the query — verify update.getSetClause()/assignments are non-empty if you keep a reference to the Hibernate API
- In dynamic builders, skip execution entirely when no assignments were produced (an empty update is usually a no-op anyway)
- Fail fast with your own validation right after building, so the message points at your code rather than Hibernate internals
Example fix
// before
CriteriaUpdate<User> u = cb.createCriteriaUpdate(User.class);
Root<User> root = u.from(User.class);
u.where(cb.equal(root.get("id"), userId));
// no u.set(...) — nothing to update
em.createQuery(u).executeUpdate(); // IllegalArgumentException
// after
if (changes.isEmpty()) { return; } // nothing changed, skip
changes.forEach((attr, val) -> u.set(root.get(attr), val));
em.createQuery(u).executeUpdate(); Defensive patterns
Strategy: validation
Validate before calling
if (changes.isEmpty()) { return 0; } // nothing to update — skip before building
CriteriaUpdate<T> u = cb.createCriteriaUpdate(entity);
changes.forEach((attr, val) -> u.set(root.get(attr), val)); Try / catch
try { return em.createQuery(update).executeUpdate(); } catch (IllegalArgumentException e) { if (e.getMessage().contains("No assignments")) { return 0; } else throw e; } Prevention
- Treat an empty diff as a no-op and never build the update statement
- Assert update has at least one set() in a helper right before execution
- Write a test for the 'nothing changed' path of every dynamic update builder
When it happens
Trigger: CriteriaUpdate<T> update = cb.createCriteriaUpdate(T.class); update.where(...); em.createQuery(update).executeUpdate() — with no update.set(attribute, value) call, typically because a dynamic builder's set-list came out empty.
Common situations: Dynamically composed updates whose assignments are driven by a diff/patch map that is empty (nothing changed); refactors that move set() calls behind a condition; copy-pasted update templates missing the set line.
Related errors
- Illegal empty CTE name
- Illegal CTE name [%s]. Names must start with an alphabetic c
- Not enough root entities
- Cannot call getParent() on update/delete criteria
- empty selections passed to criteria query typed as Object
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/6593ba03c94c2025.
Report an issue: GitHub.