HibernateException: Illegal attempt to associate a collection with two open sessions

Solution Verified - Updated -

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP)
    • 5
    • 6
  • Hibernate
    • 3
    • 4

Issue

  • An entity with an association is created or loaded in one persistence context and subsequently updated in a different persistence context
  • The entity is passed by reference into the code operating in the second persistence context
  • The following exception is encountered during an attempt to persist changes to the database
org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions

Resolution

  • Ensure that the original persistence context is closed (entity manager/session has been closed) or that the entity has been evicted from that context and no further operations are done that might impact the entity (e.g. no commit, etc.).
  • Use the entity manager merge() method to attach the entity to the new context:
MyEntity mergedEntityReference = entityManager.merge(detachedEntityReference);
  • If working with native Hibernate (directly with the session), use the session merge() method as detailed in the Hibernate reference manual
MyEntity mergedEntityReference (MyEntity) = session.merge(detachedEntityReference);
  • Once merged, use the reference returned by the merge() API in the new persistence context (e.g. mergedEntityReference), not the original reference
  • Mark entity associations with CascadeType.MERGE or CascadeType.ALL to ensure that entity associations are automatically attached to the new session. See the discussion in the Hibernate referenced manual.
  • Do not use any cached references to the entity's associated entities that were created prior to the merge in the new context
  • Note that the entity manager contains() or the Hibernate session contains() methods may be used to determine if an entity is attached to the current persistence context.
  • The entity manager detach() or session evict() methods may be used to explicitly remove an entity from the original persistence context (i.e. detaching it)
  • There are plans to improve "first failure" exception capture in future releases

Root Cause

  • An entity or collection of entities persisted or loaded in one persistence context (using the native Hibernate session directly or the JPA entity manager) is associated with the original context and retains a reference to the underlying Hibernate session until it is detached or until it is merged to a new persistence context.
  • In order to be used in a new persistence context (with a new entity manager and/or the underlying Hibernate session), the entity must be attached to the new context
  • Note that, per the JPA 2.0 specification, "[i]t is the responsibility of the application to insure that an instance is managed in only a single persistence context. The behavior is undefined if the same Java instance is made managed in more than one persistence context." (3.2.8)

Diagnostic Steps

  • Enable TRACE for org.hibernate
  • With EAP 6/Hibernate 4, enable TRACE for org.jboss.as.jpa

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Close

Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.