hibernate/hibernate-orm · error · IllegalArgumentException

Instance ID must be a positive value

Error message

Instance ID must be a positive value

What it means

InstanceIdentityStore.put(Object key, int instanceId, V value) requires instanceId > 0 and throws IllegalArgumentException otherwise. The id is assigned by Hibernate bytecode enhancement when an instance first touches a persistence context; id 0 (the unset value) means the class was not enhanced or the instance was never registered — so the store refuses to address slot -1/0-derived indexes with an unassigned id.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/internal/util/collections/InstanceIdentityStore.java:84

				);
			}
		}
		return null;
	}

	/**
	 * Associates the specified value with the specified key in this store (optional operation). If the store
	 * previously contained a mapping for the key, the old value is replaced by the specified value.
	 *
	 * @param key key with which the specified value is to be associated
	 * @param value value to be associated with the specified key
	 */
	public void put(Object key, int instanceId, V value) {
		if ( key == null ) {
			throw new NullPointerException( "This store does not support null keys" );
		}
		else if ( instanceId <= 0 ) {
			throw new IllegalArgumentException( "Instance ID must be a positive value" );
		}

		final int keyIndex = toKeyIndex( instanceId );
		final Page<Object> page = getOrCreateEntryPage( keyIndex );
		final int pageOffset = toPageOffset( keyIndex );
		page.set( pageOffset, key );
		page.set( pageOffset + 1, value );
	}

	/**
	 * Removes the mapping for an instance id from this store if it is present (optional operation).
	 *
	 * @param instanceId the instance id whose associated value is to be returned
	 * @param key key instance to double-check instance equality
	 * @implNote This method accesses the backing array with the provided instance id, but performs an instance
	 * equality check ({@code ==}) with the provided key to ensure it corresponds to the mapped one
	 */
	public void remove(int instanceId, Object key) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Run the Hibernate bytecode enhancer over the entity classes (Maven/Gradle plugin or runtime agent)
  2. Only store instances that already have an assigned id — i.e. after they became managed
  3. Guard the call: skip or fall back when $$_hibernate_getInstanceId() <= 0

Example fix

// before
store.put( entity, entity.$$_hibernate_getInstanceId(), value );
// after
int id = entity.$$_hibernate_getInstanceId();
if ( id > 0 ) {
    store.put( entity, id, value );
}
else {
    throw new IllegalStateException( "entity class not enhanced: " + entity.getClass() );
}
Defensive patterns

Strategy: validation

Validate before calling

if ( instanceId <= 0 ) {
    throw new IllegalStateException( "instance id not assigned (unenhanced or unmanaged class): " + key.getClass().getName() );
}
store.put( key, instanceId, value );

Type guard

static boolean hasAssignedInstanceId(Object entity, int instanceId) {
    return entity != null && instanceId > 0;
}

Prevention

When it happens

Trigger: put(entity, 0, value) with an unenhanced entity class ($$_hibernate_getInstanceId() returns 0); putting a transient instance before it became managed; passing a manually computed id that is <= 0.

Common situations: Bytecode enhancement disabled or missing from the build while code assumes enhanced entities; test fixtures instantiating entities directly and inserting them into persistence-context-adjacent stores; mixed enhanced/unenhanced classes after a build change.

Related errors


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