hibernate/hibernate-orm · error · IllegalArgumentException

Instance ID must be a positive value

Error message

Instance ID must be a positive value

What it means

put() computes the storage index as key.$$_hibernate_getInstanceId() - 1. An id of 0 (or negative) yields index < 0 and this IllegalArgumentException. Id 0 means the enhancement runtime never assigned an instance id — classically because the entity class is not bytecode-enhanced, or the instance has not yet been registered where ids get assigned.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/internal/util/collections/InstanceIdentityMap.java:153

	 * since we need to do a type check. Prefer using {@link #get(int, Object)}.
	 */
	@Override
	public @Nullable V get(Object key) {
		if ( key instanceof InstanceIdentity instance ) {
			return get( instance.$$_hibernate_getInstanceId(), instance );
		}
		throw new ClassCastException( "Provided key does not support instance identity" );
	}

	@Override
	public @Nullable V put(K key, V value) {
		if ( key == null ) {
			throw new NullPointerException( "This map does not support null keys" );
		}

		final int index = key.$$_hibernate_getInstanceId() - 1;
		if ( index < 0 ) {
			throw new IllegalArgumentException( "Instance ID must be a positive value" );
		}

		final Map.Entry<K, V> old = set( index, new AbstractMap.SimpleImmutableEntry<>( key, value ) );
		if ( old == null ) {
			size++;
			return null;
		}
		else {
			return old.getValue();
		}
	}

	/**
	 * Removes the mapping for an instance id from this map 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
	 * @return the previous value associated with {@code instanceId}, or {@code null} if there was no mapping for it.

View on GitHub (pinned to fad1729dce)

Solutions

  1. Enable Hibernate bytecode enhancement for the entity classes (Maven/Gradle enhancer plugin or agent)
  2. Only put instances that are already managed — with a positive assigned instance id
  3. If enhancement is off by design, use a regular HashMap instead of instance-identity collections
  4. Verify at startup that entity classes implement org.hibernate.engine.spi.InstanceIdentity

Example fix

// before
map.put( entity, state ); // entity not enhanced -> id 0 -> throws
// after
if ( entity instanceof InstanceIdentity i && i.$$_hibernate_getInstanceId() > 0 ) {
    map.put( entity, state );
}
else {
    fallbackMap.put( entity.getId(), state );
}
Defensive patterns

Strategy: validation

Validate before calling

if ( key instanceof org.hibernate.engine.spi.InstanceIdentity id
        && id.$$_hibernate_getInstanceId() > 0 ) {
    map.put( key, value );
} else {
    throw new IllegalStateException( "entity not enhanced or not managed: " + key.getClass() );
}

Type guard

static boolean hasAssignedInstanceId(Object entity) {
    return entity instanceof org.hibernate.engine.spi.InstanceIdentity id
            && id.$$_hibernate_getInstanceId() > 0;
}

Prevention

When it happens

Trigger: put(pojoEntity, value) where the entity class lacks enhancement so $$_hibernate_getInstanceId() returns 0; putting a freshly created entity before it became managed/enhanced.

Common situations: Using InstanceIdentityMap/related structures with plain POJOs in tests; enhancement disabled in the build (plugin not applied) while runtime code assumes it; dev-time classpath where enhanced and unenhanced versions mix.

Related errors


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