hibernate/hibernate-orm · error · HibernateException

The query attempts to update an immutable entity: ${querySpa

Error message

The query attempts to update an immutable entity: ${querySpaces} (set 'hibernate.query.immutable_entity_update_query_handling_mode' to suppress)

What it means

Entities mapped @Immutable (or mutable=false) must not be updated by design, and Hibernate polices bulk UPDATE statements at validation time. The setting hibernate.query.immutable_entity_update_query_handling_mode selects the reaction: WARNING logs, ALLOW logs at core level, and EXCEPTION (the default) throws HibernateException listing the entity's query spaces. Note the update also silently does nothing at runtime in some modes — the setting only controls detection messaging.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/sqm/tree/spi/update/SqmUpdateStatement.java:177

			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 );
					break;
				case EXCEPTION:
					throw new HibernateException( "The query attempts to update an immutable entity: "
												+ querySpaces
												+ " (set '"
												+ AvailableSettings.IMMUTABLE_ENTITY_UPDATE_QUERY_HANDLING_MODE
												+ "' to suppress)");
			}
		}
	}

	private void verifyUpdateTypesMatch() {
		final List<SqmAssignment<?>> assignments = getSetClause().getAssignments();
		for ( int i = 0; i < assignments.size(); i++ ) {
			final SqmAssignment<?> assignment = assignments.get( i );
			final SqmPath<?> targetPath = assignment.getTargetPath();
			final SqmExpression<?> expression = assignment.getValue();
			assertAssignable( null, targetPath, expression, nodeBuilder() );
		}
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove the update path — an immutable entity is not supposed to change; delete-and-insert instead if the data must change
  2. If the update is intentional and accepted, relax detection: set hibernate.query.immutable_entity_update_query_handling_mode=warning (or allow) in persistence.xml/spring.jpa.properties
  3. If the entity really needs mutation, remove @Immutable / set mutable=true in the mapping and re-run your concurrency tests

Example fix

# before (default EXCEPTION)
# UPDATE on an @Immutable entity throws HibernateException

# after — accept the update deliberately
spring.jpa.properties.hibernate.query.immutable_entity_update_query_handling_mode=warning

// or better: remove the update code for immutable entities
Defensive patterns

Strategy: validation

Validate before calling

// Check mutability before issuing a bulk update
EntityType<?> et = emf.getMetamodel().entity(entityName);
boolean immutable = et.getJavaType().isAnnotationPresent(org.hibernate.annotations.Immutable.class);
if (immutable) throw new UnsupportedOperationException("Refusing to update immutable entity " + entityName);

Type guard

static boolean isImmutableEntity(EntityManagerFactory emf, Class<?> type) {
    return type.isAnnotationPresent(org.hibernate.annotations.Immutable.class);
}

Try / catch

try { em.createQuery(update).executeUpdate(); } catch (HibernateException e) { if (e.getMessage().contains("immutable entity")) { /* log config mistake and rethrow or skip */ } else throw e; }

Prevention

When it happens

Trigger: Executing HQL 'UPDATE ImmutableEntity SET ...' or a CriteriaUpdate against an @Immutable entity while the handling mode is EXCEPTION (default). Also triggered by generic bulk-update helpers that sweep many entity types, some of which are immutable.

Common situations: Marking entities immutable for caching/read-model performance while legacy update code paths remain; tests that reuse production mappings with @Immutable value objects; teams enabling stricter handling modes after an audit.

Related errors


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