hibernate/hibernate-orm · error · HibernateException

An immutable attribute [%s] within compound natural identifi

Error message

An immutable attribute [%s] within compound natural identifier of entity %s was altered from `%s` to `%s`

What it means

Error "An immutable attribute [%s] within compound natural identifier of entity %s was altered from `%s` to `%s`" thrown in hibernate/hibernate-orm.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/CompoundNaturalIdMapping.java:231

		if ( !isMutable() ) {
			final var persistenceContext = session.getPersistenceContextInternal();
			final var persister = getDeclaringType().getEntityPersister();

			final Object[] naturalId = extractNaturalIdFromEntityState( currentState );
			final Object snapshot = loadedState == null
					? persistenceContext.getNaturalIdSnapshot( id, persister )
					: persister.getNaturalIdMapping().extractNaturalIdFromEntityState( loadedState );
			final Object[] previousNaturalId = (Object[]) snapshot;
			assert naturalId.length == getNaturalIdAttributes().size();
			assert previousNaturalId.length == naturalId.length;

			for ( int i = 0; i < getNaturalIdAttributes().size(); i++ ) {
				final var attributeMapping = getNaturalIdAttributes().get( i );
				if ( !attributeMapping.getAttributeMetadata().isUpdatable() ) {
					final Object currentValue = naturalId[i];
					final Object previousValue = previousNaturalId[i];
					if ( !attributeMapping.areEqual( currentValue, previousValue, session ) ) {
						throw new HibernateException(
								String.format(
										"An immutable attribute [%s] within compound natural identifier of entity %s was altered from `%s` to `%s`",
										attributeMapping.getAttributeName(),
										persister.getEntityName(),
										previousValue,
										currentValue
								)
						);
					}
				}
				// else property is updatable (mutable), there is nothing to check
			}
		}
		// otherwise the natural id is mutable (!immutable), no need to do the checks
	}

	@Override
	public boolean areEqual(Object one, Object other, SharedSessionContractImplementor session) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Do not modify attributes that are part of an immutable (non-mutable) natural id; create a new entity instead.
  2. Mark the natural id as mutable (mutable=true) if changes are intended.

When it happens

Trigger: Thrown at flush time when an attribute marked immutable within a compound natural id has been changed between snapshots.

Common situations: See trigger scenarios.


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