How to manage EntityManager life-cycle in CDI environment (using Tomcat)

It's not about CDI. EntityManager's life cycle depends on its type, which can be:

  1. container-managed transactional,
  2. container-managed extended,
  3. application-managed.

The first two are only available in a full-blown application server. So if you're going to stick with a servlet container you're narrowed to the 3rd option.

You will have to explicitly open and close EMs in your application. It's straightforward: create an application-wide instance of EntityManagerFactory, inject it to all your beans. When you need an EM just create it, use and then immediately close without waiting for your bean's context to end. Because in this configuration an open EntityManager will retain a connection and with long-lived beans you'll run out of connections. You can find an easy and comprehensive explanation in the Obtaining a JPA Database Connection section of the ObjectDB manual.


You can maintain the CDI bean state using CDI Scopes. Actually EntityManagerProducer#create() missing the scope. What ever the RI of CDI you have configure/install in tomact either its Weld or OpenWebBean, you can define your cdi bean state as belwo.

@Produces @RequestScoped
public EntityManager create() {
    return emf.createEntityManager();
}

Your problem are

1. CDI, JSF and JPA2.  
2. Managing EntityManager lifecycle when using JPA in a non enterprise environment (e.g. Tomcat)

1. CDI, JSF and JPA2.

Tomcat container not support the CDI out the box, even not the JSF, you know developers had to supply the JSF jars them self's.JSF 2.2 has new CDI compatible scops @ViewScoped here's the CDI-only @FlowScoped which doesn't have an equivalent for @ManagedBean.

(1) Really If you are most interested to use CDI or CDI+JSF+JPA , then upgrade tomcat to TomEE or go with TomEE. Tomcat + Java EE = TomEE.The Java Enterprise Edition of Tomcat,With TomEE you get Tomcat with JPA.

(2) If you no control over upgrading the tomcat server, in that case you had to do i. Supply CDI and some others jar and configuration files along with weapp it self. ii. Installing CDI in tomcat (Weld, or OpenWebBeans these both are major CDI implementations)

(3) Tomcat 8. Tomcat 8 is aligned with Java EE 7.

2) Managing EntityManager lifecycle

Managing EntityManager lifecycle when using JPA in a non enterprise environment (e.g. Tomcat) or Java SE is a custom task. In this situation, you should consider the right scope of the EntityManager to use and while working with resources it's always important to ensure they are closed when not longer needed.

There are three main types of EntityManagers defined in JPA.

    Container Managed and Transaction Scoped Entity Managers
    Container Managed and Extended Scope Entity Managers
    Application Managed Entity Managers

Working with JPA there are two kind of resources we can take care of: EntityManager and transactions. In this case, you should consider the right scope of the EntityManager to use.

1. An EntityManager is not a heavyload object.
   There is no need to use the same EntityManger longer than needed,
   You can't use an EntityManager instance for the whole application lifecycle (application scope) for the EntityManager is not Thread-safe)
2. It's not safe to traverse lazy-loaded relationships once the EntityManager is closed (This situation will change as of JPA 2.0).
i.)Method scope (i.e. instantiate/destroy one EntityManager in each business method).
   The method scope is not enough for every situation. There could be some scenarios where you'll need a wide scope, such as the following situations:
   i.  When transactions spread multiple business methods.
   ii. Need to traverse lazy-loaded relationships outside a method (e.g. in a JSF page).
   In method scope be careful to ensure the EntityManger is always closed
  ii.)Request scope (on-demand creation of the EntityManager instance to use within the request service)
   EntityManager per HTTP request strategy with the following features:
    i.  Creation on demand of the EntityManager.
    ii. Lazy closing of the EntityManager. 

The main benefit of this scope is derived from the delayed closing of the EntityManager (it will last as long as a HTTP request is in process).
Every queried entity will be managed till the end of the request and therefore during the presentation phase (the render phase in JSF for instance).

In your case your are using application entity manger and application managed transaction it means its your code which is supposed to handle the transaction. In a nutshell it means:

You call:

entityManager.getTransaction().begin(); //to start a transaction

then if success you will ensure to call

entityManager.getTranasaction().commit(); //to commit changes to database

or in case of failure you will make sure to call:

entityManager.getTransaction().rollBack();

Now imagine you have a container, which knows when to call begin(), commit() or rollback(), thats container managed transaction.