JPA
specification has defined below types of EntityManagers / Persistence Contexts:
·
Extended and transaction-scoped EntityManagers,
·
container-managed or application-managed EntityManagers.
·
JTA or resource-local EntityManager,
Transaction level Persistence Context and
Extended level Persistence Context:
By default the Persistence Context level is Transaction.
What that means is Persistence Context 'lives' for the length of transaction.If
you have multiple queries using same transaction then same persistence context
is used for all of them.
As the name suggests, a
transaction-scoped persistence context is tied to the lifecycle of the
transaction. It is created by the container during a transaction and will be
closed when the transaction completes.
Transaction-scoped
entity managers are responsible for creating transaction-scoped persistence
contexts automatically when needed. We say only when needed because
transactionscoped persistence context creation is lazy.
An entity manager will
create a persistence context only when a method is invoked on the entity
manager and when there is no persistence context available.
In case of Stateless Session bean we have
business method that should end when the business method finishes because
in next invocation we don’t have an idea which EJB instance we’ll end in. One
method = one transaction; only transactional-scoped EntityManager is allowed
for SLSB.
You can control if the EntityManager is
extended or transactional during the EntityManager injection:
@PersistenceContext(type=javax.persistence.PersistenceContextType.EXTENDED)
EntityManager em;
By default it’s javax.persistence.PersistenceContextType.TRANSACTION.
The extended scope is available only for
Stateful EJBs; it makes perfectly sense as the SFSBs can save the state, so end
of one business method doesn’t necessary means the end of the transaction.
The lifecycle of an
extended persistence context is tied to the stateful session bean to which it
is bound.
Unlike a
transaction-scoped entity manager that creates a new persistence context for
each transaction, the extended entity manager of a stateful session bean always
uses the same persistence context.
The stateful session
bean is associated with a single extended persistence context that is created
when the bean instance is created and closed when the bean instance is removed.
This has implications for both the association and propagation characteristics
of the extended persistence context.
JPA provides 'Extended
Persistence Context'. This could be thought of as the Persistence Context being
'owned' by the EntityManager rather than the Transaction. In this case the same
Persistence Context can be used for multiple transactions.
JPA needs to provide
this due to the mechanism it uses to support Optimistic Concurrency Checking
for objects without a version property.
Container-managed vs
application-managed
When we
inject the EntitiyManager with @PersistenceContext as below , what we do is, we
ask Container to inject it. Which means it’s a container managed
PersistenceContext.
@PersistenceContext
EntityManager em;
Container creates is
using the EntityManagerFactory. Remember in Java SE you create it using
EntitiyManagerFactory as below, it is application managed:
EntityManagerFactory
emf =
Persistence.createEntityManagerFactory("EmployeeService");
EntityManager em =
emf.createEntityManager();
Application-Managed Entity Managers in
Java SE
@PersistenceUnit(unitName="EmployeeService")
EntityManagerFactory emf;
EntityManager em = emf.createEntityManager();
Application-Managed Entity Managers in
Java EE
Every application-managed Persistence
Context has the extended scope.
JTA vs resource-local
Container managed entity manager = JTA
EntityManager.
Application managed Entity Manager = 1. JTA
Entity Manager OR 2. Resource Local.
So if you are using application managed entity
manager then you can tell jpa to use either resource local or JTA.
In persistence.xml write :
<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
<persistence-unit
transaction-type="RESOURCE_LOCAL" ... >
</persistence>
Other value is “JTA”, which is default too.
If you use resource local then you will have
to use following :
EntityManager.getTransaction(), which
will give javax.persistence.EntityTransaction and you have to invoke begin(),
rollback(), commit();