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

## 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 in detail in Section 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

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

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

### 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 entities back into the new persistence context.

Example 7.1. Behavior of Transaction Persistence Context

The following code illustrates the behavior of entities 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 instance, 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);

### 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 entities under an `EntityManager` using an extended persistence context.

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

    // persistence context active for entire life of EM, so 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();

    // same persistence context 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, instance still managed
    Magazine mag5 = em.find(Magazine.class, magId);
    assertTrue(mag5 == mag1);

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

Prev | Up | Next
2. Obtaining EntityManagers | Home | 4. Retrieving Properties Information