0

I have such code :

   public void createTerminal(TerminalDo terminalDo) {
        final EntityManagerFactory emf = JpaFactory.getEntityManagerFactory();
        final EntityManager em = emf.createEntityManager();
        EntityTransaction etx = null;
        try {
            etx = em.getTransaction();
            etx.begin();

            // persist method make the passed Object stored in the persistence
            // context
            em.persist(terminalDo);

            etx.commit();
        } catch (Exception e) {
            if (etx != null && etx.isActive())
                etx.rollback();
            e.printStackTrace();
        } finally {
            em.close();
        }
   }

This is a transactional method. I don't know if it's possible to create another transactional method calling this already transactional one, then nesting an entity-managed transaction into another one, and is it a good practice ?

       public void makeAllThat(TerminalDo terminalDo, ApplicationDo applicationDo) {
            final EntityManagerFactory emf = JpaFactory.getEntityManagerFactory();
            final EntityManager em = emf.createEntityManager();
            EntityTransaction etx = null;
            try {
                etx = em.getTransaction();
                etx.begin();

                createTerminal(terminalDo);
                createApplication(applicationDo);
                //do many other transactions...
                .....

                etx.commit();
            } catch (Exception e) {
                if (etx != null && etx.isActive())
                    etx.rollback();
                e.printStackTrace();
            } finally {
                em.close();
            }
       }
user3332598
  • 95
  • 1
  • 12
  • I think you want to achieve what is called _transaction propagation_ in JPA. – wypieprz May 14 '14 at 21:58
  • This is exactly what I want. Is it possible to do "transaction propagation" with JPA, or is it only possible with Spring ? Or maybe CDI ? – user3332598 May 15 '14 at 13:45
  • Sorry for a late answer. From JPA point of view the _transaction propagation_ term refers to sharing a single persistence context between multiple container-managed entity managers (transaction-scoped or extended) within a single JTA transaction. Take a closer look at `@TransactionAttribute` (EJB) or `@Transactional` (Spring) and choose a proper one for you. – wypieprz Jun 06 '14 at 13:07

1 Answers1

1

What you ask is called Nested Transactions. JPA alone does not specify anything about that. A Persistence Unit can be of two types: RESOURCE_LOCAL (your case, as you work with EntityTransaction) and JTA. Also JTA is known as not requiring nested transactions. But your case is RESOURCE_LOCAL, which AFIK depends on your JDBC driver, database and database engine.

IMPORTANT NOTE: the example that you showed is an example of parallel transactions, as every EntityManager instance you create with EntityManagerFactory.createEntityManager()' is independent of each other. In your case, ifcreateApplication()fails,createTerminal()` will have its transaction commited (please do test it and comfirm that in a comment)!

Usually you come along without nested transaction and I would suggest using JTA transaction (with a framework that supports declarative transactions, like Spring or EJB), as it is really a standard nowadays.

Community
  • 1
  • 1
V G
  • 18,822
  • 6
  • 51
  • 89