hibernate/hibernate-orm · error · HibernateException

Illegal attempt to associate a ManagedEntity with two open p

Error message

Illegal attempt to associate a ManagedEntity with two open persistence contexts: {}

What it means

For bytecode-enhanced entities (ManagedEntity), Hibernate stores the EntityEntry inside the entity itself. When such an entity - already carrying an EntityEntry whose persistence context is a DIFFERENT, still-open session - is added to this EntityEntryContext, and the entity's persister is mutable, Hibernate throws: the other session (possibly another thread) may still be using that injected entry, so associating it here would corrupt both sessions. A closed other context is tolerated with a stale-entry log.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/engine/internal/EntityEntryContext.java:214

	}

	private void putImmutableManagedEntity(ManagedEntity managed, int instanceId, ImmutableManagedEntityHolder holder) {
		if ( immutableManagedEntityXref == null ) {
			immutableManagedEntityXref = new InstanceIdentityStore<>();
		}
		immutableManagedEntityXref.put( managed, instanceId, holder );
	}

	private void checkNotAssociatedWithOtherPersistenceContextIfMutable(ManagedEntity managedEntity) {
		// we only have to check mutable managedEntity
		final var entityEntry = (EntityEntryImpl) managedEntity.$$_hibernate_getEntityEntry();
		if ( entityEntry != null && entityEntry.getPersister().isMutable() ) {
			final var entryPersistenceContext = entityEntry.getPersistenceContext();
			if ( entryPersistenceContext != null && entryPersistenceContext != persistenceContext ) {
				if ( entryPersistenceContext.getSession().isOpen() ) {
					// NOTE: otherPersistenceContext may be operating on the entityEntry in a different thread.
					//       it is not safe to associate entityEntry with this EntityEntryContext.
					throw new HibernateException(
							"Illegal attempt to associate a ManagedEntity with two open persistence contexts: " + entityEntry
					);
				}
				else {
					// otherPersistenceContext is associated with a closed PersistenceContext
					CORE_LOGGER.stalePersistenceContextInEntityEntry( entityEntry.toString() );
				}
			}
		}
	}

	/**
	 * Does this entity exist in this context, associated with an {@link EntityEntry}?
	 *
	 * @param entity The entity to check
	 *
	 * @return {@code true} if it is associated with this context
	 */

View on GitHub (pinned to fad1729dce)

Solutions

  1. Close (or clear) the first session before handing the entity to another session - with the origin context closed, Hibernate logs a stale entry and proceeds.
  2. Use merge() semantics on a detached COPY rather than re-associating the same enhanced instance into a second open session.
  3. Do not cache enhanced entities across requests; cache DTOs or ids and reload per session.
  4. Ensure one thread/session 'owns' an entity at a time; never operate the same enhanced instance from two open sessions concurrently.

Example fix

// before - enhanced entity attached to two open sessions
try (Session a = sf.openSession()) { orderA = a.find(Order.class, id); }
// session a still open elsewhere; then:
try (Session b = sf.openSession()) {
    b.lock(orderA, LockMode.NONE);   // Illegal attempt ...
}
// after - close the first session, or merge a copy
try (Session b = sf.openSession()) {
    Order managed = b.merge(orderA); // detached copy gets its own entry
}
Defensive patterns

Strategy: validation

Validate before calling

// Guard: before attaching an enhanced entity to a new session, check its current entry
static boolean isAttachedToOpenSession(Object entity) {
    if (entity instanceof org.hibernate.engine.spi.ManagedEntity me) {
        var entry = me.$$_hibernate_getEntityEntry();
        return entry != null
            && entry.getPersistenceContext() != null
            && entry.getPersistenceContext().getSession().isOpen();
    }
    return false;
}
// if (isAttachedToOpenSession(order)) order = newSession.merge(order);

Type guard

static boolean isManagedEntity(Object o) {
    return o instanceof org.hibernate.engine.spi.ManagedEntity;
}

Try / catch

catch (HibernateException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Illegal attempt to associate a ManagedEntity")) {
        // close/clear the original session, or merge a copy instead of re-associating
        target = session.merge(detachedCopy);
    } else throw e;
}

Prevention

When it happens

Trigger: Loading a bytecode-enhanced entity in session A, then while A is still open passing that same instance to session B (merge/lock/refresh/saveOrUpdate/reference) so B tries to attach it; also concurrent use of one entity across threads/sessions. The check only fires for mutable persisters - immutable entities can float between contexts.

Common situations: Build-time or runtime bytecode enhancement enabled (lazy-loading/dirty-tracking instrumentation) plus code that reuses detached-ish entities in a new open session; long-lived entities cached in application memory and fed into request sessions; async processing where the originating session stays open on another thread; test suites leaking sessions per class.

Related errors


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