liveBook · Manning

Detached state

As explained in Java Persistence with Spring Data and Hibernate epub

A detached entity is an entity instance that is no longer associated with a persistence context but retains its persistent identity and state.

A detached entity is an instance that retains its database identity and loaded state but is no longer managed by a persistence context. For example, an EntityManager can find an entity during a unit of work; after the context closes, the application still holds the instance, but its data may become stale. Changes to it are not automatically written to the database. section 10.1.1 section 10.3.3

Detachment changes what the application can rely on:

  • Closing the persistence context detaches its entities. EntityManager.detach(entity) detaches one instance earlier; EntityManager.contains(entity) then returns false. section 10.1.1 section 10.3.3
  • Loaded values can be read after closure, but an uninitialized proxy cannot load more data on demand. Initialize needed data before closing the context. section 10.2.4 section 10.2.3
  • Within one persistence context, repeated lookups of an identifier return the same Java instance. Across contexts, instances with the same database identity need not be the same Java object. section 10.3.1

To save detached changes in a new unit of work, call EntityManager.merge(detachedEntity). Merge copies state onto a managed instance with the same identifier, loading one if necessary, and returns that managed instance. Continue working with the returned reference, not the old detached reference. Hibernate synchronizes the managed changes when the context flushes. section 10.3.4

Detach, then merge

After loading a User, call em.detach(user) and check that em.contains(user) is false. Change its username while detached. In a new persistence context and transaction, assign User managed = em.merge(user); make any further changes to managed before committing. section 10.3.3 section 10.3.4

Do not equate database identity with Java equality. With default Object.equals(), two instances loaded in different contexts can compare unequal despite having the same identifier; a HashSet can retain both. Where equality must work across contexts, implement equals() and hashCode() using a suitable business key, accounting for Hibernate proxies. section 10.3.1 section 10.3.2

Path: managing-data/src/test/java/com/manning/javapersistence/ch10
 /SimpleTransitionsTest.java – mergeDetached()
 
detachedUser.setUsername("johndoe");
em = emf.createEntityManager();
em.getTransaction().begin();
User mergedUser = em.merge(detachedUser);
mergedUser.setUsername("doejohn");
em.getTransaction().commit();
em.close();

Follow the two references in the merge example: the detached User supplies changes, while the returned User is the managed instance used for subsequent edits. section 10.3.4

How Java Persistence with Spring Data and Hibernate epub covers it

How deep it goes
Explains context closure, manual detachment, identity, lazy-loading limits, and merge behavior down to copying state onto a managed instance.
Examples
Uses EntityManager.detach() and merge() with User instances, plus repeated Item lookups and a HashSet to expose identity differences.
What it assumes
Builds on Java entity instances, identifiers, and persistence contexts; defines detached state through the entity lifecycle.
What you can do after
Apply it via JPA EntityManager to detach entities, merge changes, and keep using the returned managed instance.
How it connects
Connects persistence contexts, entity identity, equals() and hashCode(), lazy loading, and merging.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Java Persistence with Spring Data and Hibernate epub. The section links point to the parts of the book it draws on.