Tuesday, September 23, 2014

Transaction level Persistence Context and Extended level Persistence Context

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









No comments: