Manual Transactional Service and DAO Level for JPA with Spring

I am using JPA with Spring. If I allowed Spring to process transactions, then this is what my service level will look like if I assume that the EntityManager was correctly entered into the DAO:

MyService {

   @Transactional
   public void myMethod() {
       myDaoA.doSomething();
       myDaoB.doSomething();
    }
}

However, if I have to execute transactions manually, I must definitely pass this EntityManager instance to each of the DAOs in the transaction. Any idea how best to reorganize this? I cry ugly by making a new MyDaoA (em) or passing em to every DAO method like doSomething (em).

MyService {

   private EntityManagerFactory emf;

   public void myMethod() {
       EntityManager em = emf.createEntityManager();
       EntityTransaction tx = em.getTransaction();
       MyDaoA myDaoA = new MyDaoA(em);
       MyDaoB myDaoB = new MyDaoB(em);
       try {
           tx.begin();
           myDaoA.doSomething();
           myDaoB.doSomething();
           tx.commit();
       } catch(Exception e) {
           tx.rollback();
       }
    }
}
+5
source share
3 answers

, , EntityManager DAO .

. Spring JPA:

DAO EntityManager factory. , EntityManager ( " EntityManager", , - EntityManager) factory:

public class ProductDaoImpl implements ProductDao {

    @PersistenceContext
    private EntityManager em;

    public Collection loadProductsByCategory(String category) {
       Query query = em.createQuery(
                        "from Product as p where p.category = :category");
       query.setParameter("category", category);
       return query.getResultList(); 
    }
}

@PersistenceContext , PersistenceContextType.TRANSACTION. - , EntityManager.

+3

spring

<bean p:entityManagerFactory-ref="emf" class='org.springframework.orm.jpa.support.SharedEntityManagerBean' />

@Autowired EntityManager dao

, spring @Transactional, , , spring.xml

spring

transactionStatus = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
// do your work here 
platformTransactionManager.commit(transactionStatus );
+1

Shot in the dark a bit, I think, but did you know what you can do:

TransactionInterceptor.currentTransactionStatus (). setRollbackOnly ();

This usually eliminates most of the cases where you want / should use software transactions on a system that would otherwise have declarative transactions.

0
source

All Articles