{"record":{"id":"496fcff2756e03d6","repo":"hibernate/hibernate-orm","slug":"found-a-different-instance-corresponding-to-instan-496fcf","errorCode":null,"errorMessage":"Found a different instance corresponding to instanceId [${instanceId}], this might indicate a concurrent access to this persistence context.","messagePattern":"Found a different instance corresponding to instanceId \\[(.+?)\\], this might indicate a concurrent access to this persistence context\\.","errorType":"exception","errorClass":"ConcurrentModificationException","httpStatus":null,"severity":"critical","filePath":"hibernate-core/src/main/java/org/hibernate/internal/util/collections/InstanceIdentityStore.java","lineNumber":63,"sourceCode":"\t * @implNote This method accesses the backing array with the provided instance id, but performs an instance\n\t * equality check ({@code ==}) with the provided key to ensure it corresponds to the mapped one\n\t */\n\tpublic @Nullable V get(int instanceId, Object key) {\n\t\tif ( instanceId <= 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tfinal int keyIndex = toKeyIndex( instanceId );\n\t\tfinal Page<Object> page = getPage( keyIndex );\n\t\tif ( page != null ) {\n\t\t\tfinal int offset = toPageOffset( keyIndex );\n\t\t\tfinal Object k = page.get( offset );\n\t\t\tif ( k == key ) {\n\t\t\t\t//noinspection unchecked\n\t\t\t\treturn (V) page.get( offset + 1 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new ConcurrentModificationException(\n\t\t\t\t\t\t\"Found a different instance corresponding to instanceId [\" + instanceId +\n\t\t\t\t\t\t\"], this might indicate a concurrent access to this persistence context.\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Associates the specified value with the specified key in this store (optional operation). If the store\n\t * previously contained a mapping for the key, the old value is replaced by the specified value.\n\t *\n\t * @param key key with which the specified value is to be associated\n\t * @param value value to be associated with the specified key\n\t */\n\tpublic void put(Object key, int instanceId, V value) {\n\t\tif ( key == null ) {\n\t\t\tthrow new NullPointerException( \"This store does not support null keys\" );","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/internal/util/collections/InstanceIdentityStore.java#L45-L81","documentation":"InstanceIdentityStore.get(Object key, int instanceId) reads the key slot for instanceId (keys and values occupy adjacent slots: offset and offset+1) and checks k == key. A different object in the slot means the same instance id maps to two distinct instances — only possible if the store/persistence context is accessed concurrently — so it throws ConcurrentModificationException naming the instanceId. It is an integrity alarm, not a normal miss (misses return null).","triggerScenarios":"Thread B put() a different key under the same instanceId between thread A's slot read and identity check; the store is not internally synchronized, so any cross-thread sharing of the owning persistence context can interleave this way.","commonSituations":"One Hibernate Session used from multiple threads (parallel streams triggering lazy loads, @Async handlers, hand-rolled pools); tests that hammer a Session from several threads to 'speed up' setup.","solutions":["Give each thread its own Session; the persistence context is single-threaded by contract","Synchronize all external access to shared persistence-context state if sharing is unavoidable","Log thread names on every session operation during the investigation to find the second actor","Close the corrupted Session; do not attempt to repair it mid-flight"],"exampleFix":"// before\nObject cached = store.get( entity, id ); // entity id reused across threads\n// after: verify same-instance usage and single-threaded context\nassert Thread.currentThread() == ownerThread;\nObject cached = ( entity == lastPut ) ? store.get( entity, id ) : null;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    return store.get( key, instanceId );\n} catch ( ConcurrentModificationException e ) {\n    // instance identity corrupted by concurrent access — abort, close session\n    throw new IllegalStateException(\"Persistence context accessed concurrently\", e);\n}","preventionTips":["Treat the persistence context as thread-confined; open a Session per thread/task","Never cache Sessions in shared fields or thread-local pools spanning tasks","Reproduce suspected races with concurrent integration tests before they surface in production"],"tags":["hibernate","concurrency","thread-safety","persistence-context","instance-identity"],"backgroundTag":"session-concurrent-access","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}