Entity Management in JPA 2.0

Entities are managed by the entity manager. The entity manager is represented by javax.persistence.EntityManager instances. Each EntityManager instance is associated with a persistence context. A persistence context defines the scope under which particular entity instances are created, persisted, and removed.

The Persistence Context:

A persistence context is a set of managed entity instances that exist in a particular data store. The EntityManager interface defines the methods that are used to interact with the persistence context.

The EntityManager Interface:

The EntityManager API creates and removes persistent entity instances, finds entities by the entity’s primary key, and allows queries to be run on entities.
  • Container-Managed Entity Managers:

    • With a container-managed entity manager, an EntityManager instance’s persistence context is automatically propagated by the container to all application components that use the EntityManager instance within a single Java Transaction Architecture (JTA) transaction
    • JTA transactions usually involve calls across application components. To complete a JTA transaction, these components usually need access to a single persistence context. This occurs when an EntityManager is injected into the application components by means of the javax.persistence.PersistenceContext annotation
    • The persistence context is automatically propagated with the current JTA transaction, and EntityManager references that are mapped to the same persistence unit provide access to the persistence context within that transaction. By automatically propagating the persistence context, application components don’t need to pass references to EntityManager instances to each other in order to make changes within a single transaction
    • The Java EE container manages the life cycle of container-managed entity managers
To obtain an EntityManager instance, inject the entity manager into the application component:
@PersistenceContext
EntityManager em;
  • Application-Managed Entity Managers:

    • With application-managed entity managers, on the other hand, the persistence context is not propagated to application components, and the life cycle of EntityManager instances is managed by the application
    • Application-managed entity managers are used when applications need to access a persistence context that is not propagated with the JTA transaction across EntityManager instances in a particular persistence unit. In this case, each EntityManager creates a new, isolated persistence context. The EntityManager and its associated persistence context is created and destroyed explicitly by the application
    • Applications create EntityManager instances in this case by using the createEntityManager method of javax.persistence.EntityManagerFactory.
    • To obtain an EntityManager instance, you first must obtain an EntityManagerFactory instance by injecting it into the application component by means of the javax.persistence.PersistenceUnit annotation:
@PersistenceUnit
EntityManagerFactory emf;
Then, obtain an EntityManager from the EntityManagerFactory instance:
EntityManager em = emf.createEntityManager();
  • Finding Entities Using the EntityManager:

The EntityManager.find method is used to look up entities in the data store by the entity’s primary key.
@PersistenceContext
EntityManager em;
public void enterOrder(int custID, Order newOrder) {
    Customer cust = em.find(Customer.class, custID);
    cust.getOrders().add(newOrder);
    newOrder.setCustomer(cust);
}
  • Managing an Entity Instance’s Life Cycle:

    • You manage entity instances by invoking operations on the entity by means of an EntityManager instance. Entity instances are in one of four states: new, managed, detached or removed.
    • New entity instances have no persistent identity and are not yet associated with a persistence context.
    • Managed entity instances have a persistent identity and are associated with a persistence context.
    • Detached entity instances have a persistent identity and are not currently associated with a persistence context.
    • Removed entity instances have a persistent identity, are associated with a persistent context, and are scheduled for removal from the data store.

Persisting Entity Instances

New entity instances become managed and persistent either by invoking the persist method or by a cascading persist operation invoked from related entities that have the cascade=PERSIST or cascade=ALL elements set in the relationship annotation. This means the entity’s data is stored in the database when the transaction associated with the persist operation is completed.
If the entity is already managed, the persist operation is ignored, although the persist operation will cascade to related entities that have the cascade element set to PERSIST or ALL in the relationship annotation. If persist is called on a removed entity instance, it becomes managed. If the entity is detached, persist will throw an IllegalArgumentException, or the transaction commit will fail.
@PersistenceContext
EntityManager em;
...
public LineItem createLineItem(Order order, Product product,
        int quantity) {
    LineItem li = new LineItem(order, product, quantity);
    order.getLineItems().add(li);
    em.persist(li);
    return li;
}
The persist operation is propagated to all entities related to the calling entity that has the cascade element set to ALL or PERSIST in the relationship annotation.
@OneToMany(cascade=ALL, mappedBy="order")
public Collection getLineItems() {
    return lineItems;
}

Removing Entity Instances

Managed entity instances are removed by invoking the remove method, or by a cascading remove operation invoked from related entities that have the cascade=REMOVE or cascade=ALL elements set in the relationship annotation. If the remove method is invoked on a new entity, the remove operation is ignored, although remove will cascade to related entities that have the cascade element set to REMOVE or ALL of the relationship annotation.
If remove is invoked on a detached entity it will throw an IllegalArgumentException, or the transaction commit will fail. If remove is invoked on an already removed entity, it will be ignored. The entity’s data will be removed from the data store when the transaction is completed, or as a result of the flush operation.
public void removeOrder(Integer orderId) {
    try {
        Order order = em.find(Order.class, orderId);
        em.remove(order);
    }...
In this example, all LineItem entities associated with the order are also removed, as Order.getLineItems has cascade=ALL set in the relationship annotation.

Synchronizing Entity Data to the Database

The state of persistent entities is synchronized to the database when the transaction with which the entity is associated commits. If a managed entity is in a bidirectional relationship with another managed entity, the data will be persisted based on the owning side of the relationship.
To force synchronization of the managed entity to the data store, invoke the flush method of the entity. If the entity is related to another entity, and the relationship annotation has the cascade element set to PERSIST or ALL, the related entity’s data will be synchronized with the data store when flush is called.
If the entity is removed, calling flush will remove the entity data from the data store.

Persistence Units

  • A persistence unit defines a set of all entity classes that are managed by EntityManager instances in an application. This set of entity classes represents the data contained within a single data store.
  • Persistence units are defined by the persistence.xml configuration file. The JAR file or directory whose META-INF directory contains persistence.xml is called the root of the persistence unit. The scope of the persistence unit is determined by the persistence unit’s root.
  • Each persistence unit must be identified with a name that is unique to the persistence unit’s scope.
  • Persistent units can be packaged as part of a WAR or EJB JAR file or can be packaged as a JAR file that can then be included in a WAR or EAR file.
  • If you package the persistent unit as a set of classes in an EJB JAR file, persistence.xml should be put in the EJB JAR’s META-INF directory.
  • If you package the persistence unit as a set of classes in a WAR file, persistence.xml should be located in the WAR file’s WEB-INF/classes/META-INF directory.
  • If you package the persistence unit in a JAR file that will be included in a WAR or EAR file, the JAR file should be located:
  • In the WEB-INF/lib directory of a WAR.
  • In the top-level of an EAR file.

In the EAR file’s library directory.

The persistence.xml File

Persistence.xml defines one or more persistence units. The following is an example persistence.xml file.This unit manages orders and customers.It does not rely on any vendor-specific features and can, therefore, be deployed to any persistence provider.

jdbc/MyOrderDB
MyOrderApp.jar
com.widgets.Order
com.widgets.Customer

This file defines a persistence unit named Oxyzium, which uses a JTA-aware data source jdbc/MyOrderDB. The jar-file and class elements specify managed persistence classes: entity classes, embeddable classes, and mapped superclasses. The jar-file element specifies JAR files that are visible to the packaged persistence unit that contains managed persistence classes, while the class element explicitly names managed persistence classes.
The jta-data-source (for JTA-aware data sources) and non-JTA-data-source (non-JTA-aware data sources) elements specify the global JNDI name of the data source to be used by the container.

Resource: www.oracle.com