java - JPA 和 Spring 的手动事务服务和 DAO 层

标签 java hibernate spring jpa transactions

我正在将 JPA 与 Spring 结合使用。如果我让 Spring 处理事务,那么假设 EntityManager 已正确注入(inject)到 DAO 中,我的服务层将如下所示:

MyService {

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

但是,如果我要手动执行事务,我必须确保将 EntityManager 的实例传递到事务中的每个 DAO。知道如何更好地重构吗?我觉得做 new MyDaoA(em) 或将 em 传递到每个 DAO 方法(如 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();
       }
    }
}

最佳答案

However, if I were to do transactions manually, I have to make sure to pass that instance of EntityManager into each of the DAOs within a transaction.

这就是你错的地方。来自 Spring Reference,JPA section :

The main problem with such a DAO is that it always creates a new EntityManager through the factory. You can avoid this by requesting a transactional EntityManager (also called "shared EntityManager" because it is a shared, thread-safe proxy for the actual transactional EntityManager) to be injected instead of the 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(); 
    }
}

The @PersistenceContext annotation has an optional attribute type, which defaults to PersistenceContextType.TRANSACTION. This default is what you need to receive a shared EntityManager proxy.

关于java - JPA 和 Spring 的手动事务服务和 DAO 层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5812262/

相关文章:

java - JPA - OneToMany, ManyToOne, OneToOne 问题

java - JSP 不显示对象列表中的表

java - 在java中创建一个类的多个实例

java - 注册和登录之间应该使用哪些箭头?

java - Java中如何访问特定子类的方法?

java - Spring注入(inject)接口(interface)实现

java - spring boot Autowiring 和在 Autowiring 类上使用 new 关键字的区别?

java - 我想将最终变量初始化为函数

java - Tomcat 安全管理器 - c3p0 和 hibernate

java - JPA : How to compare two dates