7.3. Persistence Context
Prev | Chapter 7. EntityManagerFactory | Next

## 7.3. Persistence Context

A persistence context is a set of entities such that for any persistent identity there is a unique entity instance. Within a persistence context, entities are managed. The `EntityManager` controls their lifecycle, and they can access datastore resources.

When a persistence context ends, previously-managed entities become detached. A detached entity is no longer under the control of the `EntityManager`, and no longer has access to datastore resources. We discuss detachment is detail in Section 8.2, “Entity Lifecycle Management”. For now, it is sufficient to know that detachment has two obvious consequences:

1. The detached entity cannot load any additional persistent state.

2. The `EntityManager` will not return the detached entity from `find`, nor will queries include the detached entity in their results. Instead, `find` method invocations and query executions that would normally incorporate the detached entity will create a new managed entity with the same identity.

| Note
Kodo offers several features related to detaching entities. See Section 11.1, “Detach and Attach” in the Reference Guide. In particular, Section 11.1.3, “Defining the Detached Object Graph” describes how to use the `DetachState` setting to boost the performance of merging detached entities.

Injected `EntityManager`s use a transaction persistence context, while `EntityManager`s obtained through the `EntityManagerFactory` have an extended persistence context. We describe these persistence context types below.

### 7.3.1. Transaction Persistence Context

Under the transaction persistence context model, an `EntityManager` begins a new persistence context with each transaction, and ends the context when the transaction commits or rolls back. Within the transaction, entities you retrieve through the `EntityManager` or via `Queries` are managed entities. They can access datastore resources to lazy-load additional persistent state as needed, and only one entity may exist for any persistent identity.

When the transaction completes, all entities lose their association with the `EntityManager` and become detached. Traversing a persistent field that wasn't already loaded now has undefined results. And using the `EntityManager` or a `Query` to retrieve additional objects may now create new instances with the same persistent identities as detached instances.

If you use an `EntityManager` with a transaction persistence context model outside of an active transaction, each method invocation creates a new persistence context, performs the method action, and ends the persistence context. For example, consider using the `EntityManager.find` method outside of a transaction. The `EntityManager` will create a temporary persistence context, perform the find operation, end the persistence context, and return the detached result object to you. A second call with the same id will return a second detached object.

When the next transaction begins, the `EntityManager` will begin a new persistence context, and will again start returning managed entities. As you'll see in Chapter 8, EntityManager, you can also merge the previously-detached entites back into the new persistence context.

Example 7.1. Behavior of Transaction Persistence Context

The following code illustrates the behavior of entites under an `EntityManager` using a transaction persistence context.

    EntityManager em; // Injected
    ...

    // Outside a transaction:

    // Each operation occurs in a separate persistence context and returns
    // a new detached instance.
    Magazine mag1 = em.find (Magazine.class, magId);
    Magazine mag2 = em.find (Magazine.class, magId);
    assertTrue (mag2 != mag1);
    ...

    // Transaction begins:

    // Within a transaction, a subsequent lookup doesn't return any of the
    // detached objects.  However, two lookups within the same transaction
    // return the same instanc, because the persistence context spans the
    // transaction.
    Magazine mag3 = em.find (Magazine.class, magId);
    assertTrue (mag3 != mag1 && mag3 != mag2);
    Magazine mag4 = em.find (Magazine.class (magId);
    assertTrue (mag4 == mag3);
    ...

    // Transaction commits:

    // Once again, each operation returns a new instance.
    Magazine mag5 = em.find (Magazine.class, magId);
    assertTrue (mag5 != mag3);

### 7.3.2. Extended Persistence Context

An `EntityManager` using an extended persistence context maintains the same persistence context for its entire lifecycle. Whether inside a transaction or not, all entities returned from the `EntityManager` are managed, and the `EntityManager` never creates two entity instances to represent the same persistent identity. Entities only become detached when you finally close the `EntityManager` (or when they are serialized).

Example 7.2. Behavior of Extended Persistence Context

The following code illustrates the behavior of entites under an `EntityManager` using an extended persistence context.

    EntityManagerFactory emf = ...
    EntityManager em = emf.createEntityManager (PersistenceContextType.EXTENDED);

    // The persistence context is active for the entire life of the EM, so there is
    // only one entity for a given persistent identity.
    Magazine mag1 = em.find (Magazine.class, magId);
    Magazine mag2 = em.find (Magazine.class, magId);
    assertTrue (mag2 == mag1);

    em.getTransaction ().begin ();

    // The same persistence context is active within the transaction.
    Magazine mag3 = em.find (Magazine.class, magId);
    assertTrue (mag3 == mag1);
    Magazine mag4 = em.find (Magazine.class (magId);
    assertTrue (mag4 == mag1);

    em.getTransaction.commit ();

    // When the transaction commits, the instance is still managed.
    Magazine mag5 = em.find (Magazine.class, magId);
    assertTrue (mag5 == mag1);

    // The instance finally becomes detached when the EM closes.
    em.close ();

Prev | Up | Next
7.2. Obtaining EntityManagers | Home | 7.4. Closing the EntityManagerFactory