JPA specification defines few types of EntityManagers / Persistence Contexts. We can have:

  • extended and transactional-scoped EntityManagers,
  • container-managed or application-managed EntityManagers.
  • JTA or resource-local EntityManager,

Besides the above distinction, we also have two main contexts in which EntityManager / Persistence Context can exist – Java EE and Java SE. Not every option is available for Java EE and not every is possible in Java SE. In the rest of the post I refer to the Java EE environment.

Ok, so before we’ll proceed to the real topic of this post — which is the behaviour of the EntityManager in Java EE created manually using EntityManagerFactory — let’s just shortly describe the above EM types.

Extended vs transactional-scoped

This feature tells us if the EntityManager’s operations might span across multiple transactions. By default the Transactional Persistence Context is used which means that all changes are flushed and all managed entities become detached when the current transaction commits.

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.

With the SLSB the story is different – we have business method that must 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.

As a side note – using extended EntityManager might allow you to create some interesting solutions; take a look at Adam Bien’s no-transactional bean with transactional save method trick. He uses this approach to make all the changes automatically flushed when the transaction starts and ends (and he actually do that by invoking special, artificial method.)

Extended and transaction scoped PersistenceContext are allowed only in case of container-managed EntityManagers.

Container-managed vs application-managed

In great majority of Java EE applications you’re just injecting the EntityManager with @PersistenceContext like this:

@PersistenceContext
EntityManager em;

This actually means that you’re letting the container to inject the EntityManager for your (the container creates it from the EntityManagerFactory behind the scenes.) This means that your EntityManager is container-managed.

Alternatively, you can create an EntityManager by yourself – from the EntityManagerFactory. You can obtain it by injection:

@PersistenceUnit
EntityManagerFactory emf;

Then to get the EntityManager you need to invoke emf.createEntityManager(). And here it is – you’re now using the application-managed EntityManager. The application (you) is responsible for creation and removal of EntityManager.

Every application-managed Persistence Context has the extended scope.

You might use if if you want to have control over created EM – e.g. if you want to set some property to the underlying JPA implementor or just plug yourself before the business method put it hands on it. You will, however need to move the created EntityManager across multiple beans involved in the transaction – the container won’t do it for you and every time you invoke emf.createEntityManager() you’re creating an EntityManager that is connected to the new PersistenceContext. You might use the CDI for EntityManager’s sharing, but that’s the topic of one of the last sections.

JTA vs resource-local

This property defines if you want the JTA to manage your EntityManager’s transactions or if you want to use its direct API to begin and commit.

If you’re using container-managed EntityManager it automatically means that you have to use JTA EntityManager. If you’re using application-managed EntityManager, you can have it JTA or resource-local.

In the real-life it means that if you’re using JTA EntityManager you take care just of the higher-level transactions management either:

  • declaratively; using annotations or XML JTA transactions attributes or,
  • programmatically; using javax.transaction.UserTransaction.

If you’re using the resource-local EntityManager you need to go a bit deeper and use EntityManager.getTransaction() that returns javax.persistence.EntityTransaction and invoke commit(-), begin(-), rollback(), etc.

You define this feature in persistence.xml using transaction-type attribute:

<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
    <persistence-unit transaction-type="RESOURCE_LOCAL" ... >
</persistence>

The other possible value (and default when transaction-type is not defined) is JTA.

Application-managed JTA EntityManager in Java EE

As much as this subtitle sounds complex, knowing all the previous types of EntityManagers and PersistenceContexts you should understand exactly what if refers to.

  • “Application-managed” means that we’ll be injecting @PersistenceUnit EntityManagerFactory instead of EntityManager,
  • “Java EE” because these examples (published on github) are to be used only in Java EE Application Server,
  • “JTA” because we’ll be using the JTA transactions level, so we won’t be using javax.persistence.EntityTransaction.

Now the first thing you need to realize is how you use the JTA transactions. There are two types of JTA transactions management – container (CMT) and bean managed (BMT).

The Container Managed JTA transactions (CMT) means that you use the javax.ejb.TransactionAttribute for defining if the tx should be active and where the transaction boundaries are. This is the default JTA management type.

Alternative, you can choose to demarcate the JTA transactions yourself. This is called the Bean Managed JTA Transactions (BMT.) The application (you) is responsible for starting, rolling back or committing the transaction.

How can you control a JTA transaction? You do that using javax.transaction.UserTransaction.

How do you obtain one? Well, there are at least 3 ways to do this:

  • it’s bound to the JNDI in the component-private namespace (java:comp/UserTransaction), so you can just look it up using InitialContext or SessionContext,
  • you can use SessionContext to access it – SessionContext#getUserTransaction(),
  • because it’s bound in the well-known JNDI name, you can let the container inject it using: @Resource UserTransaction utx;.

If you have UserTransaction you can start demarcating what is to be executed within the transaction. Notice that you’re still controlling the JTA transactions – you’re not even touching the EntityManager’s resource-local transactions.

When The EntityManager is in The JTA Transaction?

Without the previous introduction you might think that the application-managed EntityManager means that you’re on your own for everything – creating, sharing EntityManager, begining tx, commiting, closing. However, knowing all the above differences you know that you can use the JTA transactions in your application-managed EntityManager.

But the question is – how to make it aware of the active JTA transaction? If we have a container-managed EntityManager we know that the container manages it all, but in case we’re on our own – how do we do that?

Actually it depends where the EntityManager was created by us.

Find some examples below (the complete code can be found on my github account:

Case 1: We invoke the following code without the active transaction (so we have TransactionAttribute.NEVER or TransactionAttribute.NOT_SUPPORTED in case of CMT or we didn’t invoke UserTransaction.begin() in case of BMT:

EntityManager em = emf.createEntityManager();  
em.persist(new Customer(firstName, lastName));

Results: The EntityManager operations don’t thrown any exception while persisting but none of the changes are committed. There is no active transaction, so no changes are made.


Case 2: We invoke the following code using BMT:

utx.begin();

EntityManager em = emf.createEntityManager();

em.persist(new Customer(firstName, lastName));

utx.commit();

Results: The new data is properly persisted during JTA commit (in the last line.)


Case 3: We invoke the following code using BMT:

EntityManager em = emf.createEntityManager();
utx.begin();

em.persist(new Customer(firstName, lastName));

utx.commit();

Results: The EntityManager is outside of the transaction because it was created before the JTA transaction was started. The changes are not persisted despite the commit of the JTA transaction. No exceptions are thrown.


In case of the second example you might ask yourself – is it possible to firstly create an EntityManager, then start a transaction and finally somehow make the EntityManager aware of the surrounding tx? And if fact yes, you can do that and that’s exactly what the EntityManager#joinTransaction() method is for. Following two cases should show you how it can be used:

Case 4: We invoke the following code using BMT:

EntityManager em = emf.createEntityManager();  
utx.begin();
em.joinTransaction();

em.persist(new Customer(firstName, lastName));

utx.commit();   

Results: Here we explicitly told the EntityManager to join the active JTA transaction. In the result, the EntityManager will flush all its changes during JTA commit.


Case 5: We invoke the following code using BMT:

EntityManager em = emf.createEntityManager();
utx.begin();

em.joinTransaction();

em.persist(new Customer(firstName, lastName));

utx.commit();

utx.begin();

em.joinTransaction();

em.persist(new Customer(firstName, lastName));

utx.commit();    

Results: Both EntityManager operations are properly persisted. Here we’ve shown that the application-managed Persistence Context can span across multiple JTA transactions (note that we didn’t create another EntityManager but just reused the one used in previous transaction.)

And here you can see what the JPA specs (JPA 2.0 Final Release) tells you regarding application-managed Persistence Context:

7.7 Application-managed Persistence Contexts

When a JTA application-managed entity manager is used, if the entity manager is created outside the scope of the current JTA transaction, it is the responsibility of the application to associate the entity manager with the transaction (if desired) by calling EntityManager.joinTransaction. If the entity manager is created outside the scope of a JTA transaction, it is not associated with the transaction unless EntityManager.joinTransaction is called.

Sharing of EntityManager Using CDI

As mentioned, if you want to share your EntityManager between components that constitutes one transaction, you should pass it manually (hey, after all it’s “application-managed”.) The CDI might be a solution here. You could produce the request scoped EntityManager and inject it into any component you need. It could look like this (in real-life you’d need to take care of disposal of EM as well):

public class Resources {

    @PersistenceUnit
    EntityManagerFactory emf;

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

Now in every bean we could have:

@Stateless
public class MyBean {

    @Inject
    EntityManager em;
}

It seems a very clean way of sharing the application-managed Persistence Context between different components that constitutes the transaction. However, the thing I feared was: knowing that the application-managed EntityManager transactionality behaviour depends on the location where it was created, such approach might sometimes give you nasty results. Take the following code as an example (it’s also available at my Github project, this class precisely here):

@Stateless
@TransactionAttribute(TransactionAttributeType.NEVER)
public class BeanABoundary {

    @Inject
    private EntityManager em;

    @EJB
    BeanB beanB;

    public void invoke() {
        em.getProperties();
        beanB.invoke();
}

}

Notice the BeanA being a non-transactional resource. Also note that we injected and invoked some operation on the EntityManager (this makes the injection to be actually performed.) Now if the BeanB is transactional and also injects and uses EntityManager – we’ll end with a non-transactional EntityManager that will not throw any exception and will not save any changes to the database.

In the case of old @PersistenceContext we’d be in a transaction because the EntityManager will be container-managed and the container would be aware of currently active transaction. The container is responsible for sharing the EntityManager between transaction boundaries. In case of shown CDI producer method, the CDI doesn’t know about running transaction and just share the EntityManager in anyway.

Of course, one may use the CDI and create a @Produces @PersistenceContext EntityManager em and then use @Inject EntityManager. This would work exactly as the @PersistenceContext EntityManager but allows us to define, e.g. a name of the persistence unit in a single place that produces the EntityManager.

This, however, is not an option if we want to have an application-managed EntityManager.

Did you like this? Share it:

21 thoughts on “Types of EntityManagers: Application-managed EntityManager

  1. Pingback: Hibernate session vs entitymanager | technoless

  2. Very well structured article. It actually compress a lot of documentation
    into a short, concise and very well structured article. Good job and thanks for the article.
    I would highly recommend this article.

    Reply
  3. Pingback: entitymanager und transaktionen | saveOrUpdate("....")

  4. Piotr,

    I made use of this today and it saved the day! Specifically I used:


    import javax.ejb.Stateless;
    import javax.enterprise.context.RequestScoped;
    import javax.enterprise.inject.Disposes;
    import javax.enterprise.inject.Produces;
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.PersistenceUnit;

    @Stateless
    public class EntityProducer {
    // @PersistenceContext(unitName = "esa2-pu")
    // private EntityManager em;
    //
    // @Produces @RequestScoped
    // public EntityManager getEntityManager() {
    // return em;
    // }

    @PersistenceUnit(name = "esa2-pu")
    EntityManagerFactory emf;

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

    public void destroyEntityManager(@Disposes EntityManager em) {
    if (em.isOpen()) {
    em.close();
    }
    }

    }

    The commented out code is what I had.

    I have two questions:

    I used this because the @Producer I had for an EntityManager from a @PersistenceContext stopped working when I moved the Crud classes to a jar separate to the @Producer.

    does this sound like what you’d expect.

    I had to add a @Stateless making that class an EJB to get the EM injection working.

    Any ideas off the top of your head why this is necessary?

    Cheers,

    Brooke

    Reply
    • Hi Brooke!

      Thanks for your comment.

      Sorry, but I need to ask – did you put beans.xml in your separate JAR where you injected the EM?

      If you would like – can you post some example structure, files or codes using gist and we can try to nail the problem :-)

      All the best,
      Piotr

      Reply
  5. Thanks for your feedback.

    Yeah tried the beans.xml and it also contains bean-discovery-mode="all".

    I’ve started building a minimal set of projects that reproduce this problem however have put this on hold as I’ve some immediate deadlines to meet.

    Reply
  6. Hi Piotr,

    I’m concious that I haven’t followed up to you kind offer of help. Producing a minimal representation of the problem has been tricky and it seems to me that in order to produce it I’ll most likely identify the problem! Which is not a bad thing of course. I’m unfortunately getting towards the pointy end of my contract and with still much to do I’m happy with my work-around. Could any discussions on this be done offline – brooke at tintuna com.

    Cheers,

    Brooke

    Reply
  7. Hi Piotr, let know if you can help me.

    I have some failed to lazily initialize a collection of role: no session or session was closed Exeptions.

    So I need to extend my session until the view layer but my entity manager is inject automatically like this:


    @PersistenceContext(unitName = "PromorenJPAService", type = PersistenceContextType.EXTENDED)
    public EntityManager em;

    It doesnt work at all, without Extedend Persistence Context I would have more issues of that.

    by the way I use Stateful and Stateless.

    I have tryed to create a filter with Session Factory by Hibernate but it didnt works well.
    I have tryed to create a filter injecting @PersistenceContext but it didnt works well because it was inject at time.

    Tks in advance

    Flavio

    Reply
  8. Hi Flavio,

    I do this. As discussed I’m having issues though I’m quite sure its not related to what I’m about to show you (Oh except I shouldn’t have to make it @Stateless – @RequestScoped should be fine):


    @Stateless
    public class EntityProducer {

    @PersistenceUnit(name = "esa2-pu")
    EntityManagerFactory emf;

    @Produces
    @RequestScoped
    public EntityManager createEntityManager() {
    EntityManager em = emf.createEntityManager();
    em.clear();
    System.out.println("EntityProducer / createEntityManager - em:" + em);
    return em;
    }

    public void destroyEntityManager(@Disposes EntityManager em) {
    // logger.info("Disposing Entity Manager");
    System.out.println("EntityProducer / destroyEntityManager - em:" + em);
    if (em.isOpen()) {
    em.close();
    }
    }

    }

    Then I use a CRUDService. Note how I join transactions:


    @Stateless
    @TransactionAttribute(TransactionAttributeType.MANDATORY)
    public class CrudService {
    @Inject
    EntityManager em;

    @Inject
    PersistUtil persistUtil;
    @Inject
    Logger logger;

    public T create(T t) {
    // EntityManager em = emf.createEntityManager();
    em.joinTransaction();
    em.persist(t);
    em.flush();
    em.refresh(t);
    return t;
    }

    public void delete(T t) {
    // EntityManager em = emf.createEntityManager();
    em.joinTransaction();
    em.remove(t);
    }

    public void delete(Class<T> type, Object id) {
    // EntityManager em = emf.createEntityManager();
    em.joinTransaction();
    Object ref = em.getReference(type, id);
    em.remove(ref);
    }

    public T merge(T t) {
    // EntityManager em = emf.createEntityManager();
    em.joinTransaction();
    T merged = (T) em.merge(t);
    return merged;
    }

    public T update(T t) {
    return this.merge(t);
    }

    ... and find helper methods ..

    }

    I hope that is what you were looking for!

    Reply
  9. You said: “If you’re using container-managed EntityManager it automatically means that you have to use JTA EntityManager.”. This is not correct: according to the JPA 2.0 spec: “Both JTA entity managers and resource-local entity managers are required to be supported in Java EE web containers and EJB containers. Within an EJB environment, a JTA entity manager is typically used.”. In JBoss, when working with a resource-local em means actually working without transactions at all, if no tx begin/commit are made.

    Reply
  10. Hey Piotr,
    What will hapeen in the following scenario?
    Will em bind to the second transaction and persistencecontext will be shared?
    EntityManager em = emf.createEntityManager();
    transaction 1- begin (CMT/BMT)
    em.persist(new Customer(firstName, lastName));
    transaction 2 – begin; (CMT/BMT)
    em.persist(new Customer(firstName, lastName));
    transaction1.commit(); (CMT/BMT)
    transaction2.commit(); (CMT/BMT)

    Reply
  11. Explanation:

    We have one master db, and mulitple client databases,
    Our goal is, At runtime we have to create “entityManagerFactory” for each client. Each client has seaperate database.
    (Runtype we are getting entityManagerFactory by passing clientcode and creating entityManager)
    also avoiding to configure the entityManagerFactory and transaction manager for each client.

    my follow structure. (1 ==> 2 ==> 3 ==> 4)
    1) controller( @Controller
    @RequestMapping(“/test”)
    @Scope(“prototype”) class level)

    2) serviceimpl(added @Service, @Scope(“prototype”) class level)

    3) components(added @Service, @Scope(“prototype”) class level)

    4) dao layer(added @Repository in class level).

    As of now, We are able to create entityManagerFactory for each client and put to map (in EntityManagerHelp.)
    1) works fine for single user update.
    2) Problem is mutliple users trying to use same operation it was saying “transaction not active”
    3) some time says “TransactionCordintor” exception.

    EntityManagerHelper:
    =========================

    private Map entityManagerFactoryMap = new HashMap();

    private EntityManagerHelper() {
    }

    @PersistenceContext(unitName = “masterPU”)
    private EntityManager masterEntityManager = null;

    @Autowired
    private PropertySource propertySource;

    @Autowired
    private ClientDAO clientDAO;

    public EntityManager getMasterEntityManager() {
    return masterEntityManager;
    }

    public void setMasterEntityManager(EntityManager masterEntityManager) {
    this.masterEntityManager = masterEntityManager;
    }

    public EntityManager getClientEntityManager(String clientCode) {
    EntityManagerFactory emf = getEntityManagerFactory(clientCode);
    return emf.createEntityManager();
    }

    private synchronized EntityManagerFactory getEntityManagerFactory(String clientCode) {
    if (entityManagerFactoryMap.containsKey(clientCode)) {
    if (entityManagerFactoryMap.get(clientCode) != null) {
    return entityManagerFactoryMap.get(clientCode);
    }
    throw new NullPointerException(“Error in getEntityManagerFactory”);
    }
    EntityManagerFactory entityManagerFactory = null;
    try {
    clientDAO.setEntityManager(getMasterEntityManager());
    Client client = clientDAO.getClient(clientCode);
    client.setDbUserName(“xyz” ); // dynamcially setting username with respect to client db.
    client.setDbPassword(“password”); //// dynamcially setting password with respect to client db.

    LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
    bean.setDataSource(getDataSource(client));
    bean.setPersistenceXmlLocation(“/META-INF/persistence.xml”);
    bean.setPersistenceUnitName(“clientPU”);
    bean.afterPropertiesSet();
    entityManagerFactory = (EntityManagerFactory)bean.getObject();
    entityManagerFactoryMap.put(clientCode, entityManagerFactory);

    // is there any way to create transactionmanager and inject entityManagerFactory and datasource.
    // idea is: we need to achieve transactionmanager dynamcially for each client
    } catch (Exception e) {
    e.printStackTrace();
    logger.error(“Error:” + e, e);
    }
    return entityManagerFactory;
    }

    private DataSource getDataSource(Client client) throws SQLException {
    String url = “jdbc:mysql://” + client.getDb_server() + “/” + client.getDb_name();
    String username = client.getDbUserName();
    String password = client.getDbPassword();
    Driver driver = new com.mysql.jdbc.Driver();
    return new SimpleDriverDataSource(driver, url, username, password);
    }

    Help me how to set TransactionManager for each EntityManagater Factory in below class.?

    Each request – in service layer
    EntityManager entityManager = entityManagerHelper.getEntityManagerFactory(“XYZ”)
    try {
    etx = entityManager.getEntityTransaction();
    baseDAO.setEntitityManager(entityManager)
    etx.begin();
    // operation – eg: baseDAO.update(list of entities)
    etx.commit();

    } catch(Exception e) {
    etx.rollback();
    }

    update method is looks like below:

    public void update(List detachedInstanceList) throws DBException {
    try {
    for (Entity detachedInstance : detachedInstanceList) {
    entityManager.merge(detachedInstance);
    }
    entityManager.flush();
    } catch (PersistenceException ex) {
    ex.printStackTrace();
    logger.error(“Exception occured while updating List of Entities – ” + clazz.getName(), ex);
    throw new customeException(ExceptionConstants.xxx, clazz.getSimpleName());
    }

    }

    java.lang.IllegalStateException: Transaction not active
    at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:103)
    at com.company.package.xxx.service.impl.ServiceImpl.update(ServiceImpl.java:402)
    at com.company.package.xxx.controller.Controller.update(Controller.java:148)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:746)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:822)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)

    Reply

Leave a reply

required


*

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>