@PersistenceContext
EntityManager em;
|
Java Platform, Enterprise Edition (Java EE) 8 The Java EE Tutorial |
| Previous | Next | Contents |
Entities are managed by the entity manager, which is represented by
javax.persistence.EntityManager instances. Each EntityManager
instance is associated with a persistence context: a set of managed
entity instances that exist in a particular data store. A persistence
context defines the scope under which particular entity instances are
created, persisted, and removed. The EntityManager interface defines
the methods that are used to interact with the persistence context.
The following topics are addressed here:
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.
The following topics are addressed here:
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 API (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 lifecycle of container-managed entity
managers.
To obtain an EntityManager instance, inject the entity manager into
the application component:
@PersistenceContext
EntityManager em;
With an application-managed entity manager, on the other hand, the
persistence context is not propagated to application components, and the
lifecycle 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 are created and destroyed explicitly by the application. They
are also used when directly injecting EntityManager instances can’t be
done because EntityManager instances are not thread-safe.
EntityManagerFactory instances are thread-safe.
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();
Application-managed entity managers don’t automatically propagate the
JTA transaction context. Such applications need to manually gain access
to the JTA transaction manager and add transaction demarcation
information when performing entity operations. The
javax.transaction.UserTransaction interface defines methods to begin,
commit, and roll back transactions. Inject an instance of
UserTransaction by creating an instance variable annotated with
@Resource:
@Resource
UserTransaction utx;
To begin a transaction, call the UserTransaction.begin method. When
all the entity operations are complete, call the
UserTransaction.commit method to commit the transaction. The
UserTransaction.rollback method is used to roll back the current
transaction.
The following example shows how to manage transactions in an application that uses an application-managed entity manager:
@PersistenceUnit
EntityManagerFactory emf;
EntityManager em;
@Resource
UserTransaction utx;
...
em = emf.createEntityManager();
try {
utx.begin();
em.persist(SomeEntity);
em.merge(AnotherEntity);
em.remove(ThirdEntity);
utx.commit();
} catch (Exception e) {
utx.rollback();
}
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, CustomerOrder newOrder) {
Customer cust = em.find(Customer.class, custID);
cust.getOrders().add(newOrder);
newOrder.setCustomer(cust);
}
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.
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 that the
entity’s data is stored to 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, the entity becomes
managed. If the entity is detached, either persist will throw an
IllegalArgumentException, or the transaction commit will fail. The
following method performs a persist operation:
@PersistenceContext
EntityManager em;
...
public LineItem createLineItem(CustomerOrder 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 have the cascade element set to ALL or PERSIST
in the relationship annotation:
@OneToMany(cascade=ALL, mappedBy="order")
public Collection<LineItem> getLineItems() {
return lineItems;
}
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 in the relationship annotation. If remove is invoked
on a detached entity, either remove will throw an
IllegalArgumentException, or the transaction commit will fail. If
invoked on an already removed entity, remove 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.
In the following example, all LineItem entities associated with the
order are also removed, as CustomerOrder.getLineItems has
cascade=ALL set in the relationship annotation:
public void removeOrder(Integer orderId) {
try {
CustomerOrder order = em.find(CustomerOrder.class, orderId);
em.remove(order);
}...
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 EntityManager instance. 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.
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 following is an example persistence.xml file:
<persistence>
<persistence-unit name="OrderManagement">
<description>This unit manages orders and customers.
It does not rely on any vendor-specific features and can
therefore be deployed to any persistence provider.
</description>
<jta-data-source>jdbc/MyOrderDB</jta-data-source>
<jar-file>MyOrderApp.jar</jar-file>
<class>com.widgets.CustomerOrder</class>
<class>com.widgets.Customer</class>
</persistence-unit>
</persistence>
This file defines a persistence unit named OrderManagement, 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 contain
managed persistence classes, whereas the class element explicitly
names managed persistence classes.
The jta-data-source (for JTA-aware data sources) and
non-jta-data-source (for non-JTA-aware data sources) elements specify
the global JNDI name of the data source to be used by the container.
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 an 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 either
The WEB-INF/lib directory of a WAR
Or the EAR file’s library directory
Note: In the Java Persistence API 1.0, JAR files could be located at the root of an EAR file as the root of the persistence unit. This is no longer supported. Portable applications should use the EAR file’s library directory as the root of the persistence unit. |
| Previous | Next | Contents |
Copyright © 2017, Oracle and/or its affiliates. All rights reserved.