# EntityManagerFactory

The EntityManagerFactory creates EntityManager instances for application use.

OpenJPA extends the standard EntityManagerFactory interface with the OpenJPAEntityManagerFactory to provide additional functionality.

## Obtaining an EntityManagerFactory

Within a container, you will typically use injection to access an EntityManagerFactory. There are, however, alternative mechanisms for EntityManagerFactory construction.

Some vendors may supply public constructors for their EntityManagerFactory implementations, but we recommend using the Java Connector Architecture (JCA) in a managed environment, or the Persistence class' createEntityManagerFactory methods in an unmanaged environment, as described in . These strategies allow vendors to pool factories, cutting down on resource utilization.

JPA allows you to create and configure an EntityManagerFactory, then store it in a Java Naming and Directory Interface (JNDI) tree for later retrieval and use.

JNDI
EntityManagerFactory construction
Java Connector Architecture JCA
JCA

## Obtaining EntityManagers

    public EntityManager createEntityManager();
    public EntityManager createEntityManager(Map map);

The two createEntityManager methods above create a new EntityManager each time they are invoked. The optional Map is used to supply vendor-specific settings. If you have configured your implementation for JTA transactions and a JTA transaction is active, the returned EntityManager will be synchronized with that transaction.

OpenJPA recognizes the following string keys in the map supplied to createEntityManager:

- `openjpa.ConnectionUserName`

- `openjpa.ConnectionPassword`

- `openjpa.ConnectionRetainMode`

- `openjpa.TransactionMode`

- `openjpa.<property>`, where <property> is any JavaBean property of the org.apache.openjpa.persistence.OpenJPAEntityManager.

The last option uses reflection to configure any property of OpenJPA's EntityManager implementation with the value supplied in your map. The first options correspond exactly to the same-named OpenJPA configuration keys described in of the Reference Guide.

EntityManager obtaining EntityManagerFactory
EntityManagerFactory obtaining EntityManagers

## 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 . 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.

OpenJPA offers several features related to detaching entities. See in the Reference Guide. in particular describes how to use the `DetachState` setting to boost the performance of merging detached entities.

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

### 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 , you can also merge the previously-detached entities back into the new persistence context.

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);

### 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).

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();

persistence context
PersistenceContextType persistence context

## Retrieving Properties Information

&properties_info.xml;
EntityManagerFactory properties information

## Closing the EntityManagerFactory

    public boolean isOpen();
    public void close();

EntityManagerFactory instances are heavyweight objects. Each factory might maintain a metadata cache, object state cache, EntityManager pool, connection pool, and more. If your application no longer needs an EntityManagerFactory, you should close it to free these resources. When an EntityManagerFactory closes, all EntityManagers from that factory, and by extension all entities managed by those EntityManagers, become invalid. Attempting to close an EntityManagerFactory while one or more of its EntityManagers has an active transaction may result in an IllegalStateException.

Closing an EntityManagerFactory should not be taken lightly. It is much better to keep a factory open for a long period of time than to repeatedly create and close new factories. Thus, most applications will never close the factory, or only close it when the application is exiting. Only applications that require multiple factories with different configurations have an obvious reason to create and close multiple EntityManagerFactory instances. Once a factory is closed, all methods except isOpen throw an IllegalStateException.

EntityManagerFactory closing

## PersistenceUnitUtil

    public PersistenceUnitUtil getPersistenceUnitUtil();

The EntityManagerFactory method getPersistenceUnitUtil provides access to a PersistenceUnitUtil utility. PersistenceUnitUtil can be used to obtain the identity of a managed object and determine the load state of the entity or one of its attributes. If the object is not managed by one of the entity managers created from the entity manager factory from which the utility was obtained, the getIdentifier method will return null and the isLoaded methods will return false.

    EntityManagerFactory emf = Persistence.createEntityManagerFactory();
    PersistenceUnitUtil puUtil = emf.getPersistenceUnitUtil();

    if (puUtil.getIdentifier(deptEntity) == null) {
        throw new Exception("Identity is not valid.");
    }
    if (!puUtil.isLoaded(deptEntity, "employees")) {
        throw new Exception("Employees not loaded.");
    }

EntityManagerFactory util
EntityManagerFactory