2011-04-28 117 views
5

我正在使用JPA和Spring。如果我让Spring处理事务,那么这是我的服务层将是什么样子假设的EntityManager已经正确注入的DAO:用于JPA的手动事务服务和DAO层与弹簧

MyService { 

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

不过,如果我是做手工交易,我有确保将EntityManager的实例传递到事务内的每个DAO中。任何想法如何能更好地重构?我收取新的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(); 
     } 
    } 
} 

回答

3

不过,如果我是做手工交易 ,我必须确保通过 的EntityManager的该实例到 每个的DAO的事务中。

这是你错了的地方。从Spring参考,JPA section

的主要问题有这样的DAO是 它总是通过工厂创建一个新的 的EntityManager。 您 可以通过请求 事务的EntityManager避免这种(也 称为“共享EntityManager的”,因为 它是为 实际交易 EntityManager的共享,线程安全的代理)被注入的,而非工厂的 :

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代理

+1

我还不清楚,我怎么会去这样做手工交易与服务和DAO层。 – Langali 2011-04-28 15:59:46

+0

a)如果我必须这样做,我可能会使用TransactionTemplate或JpaTemplate b)不要这样做。这是一个痛苦。 – 2011-04-28 16:02:00

+0

对不起,这超出了这个问题的范围。阅读Spring参考资料,特别是交易管理部分http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html和ORM http://static.springsource.org /spring/docs/3.0.x/spring-framework-reference/html/orm.html(提示:异常翻译是你的朋友) – 2011-04-28 16:58:03

1

添加到您的Spring配置

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

现在你可以@Autowired的EntityManager你的DAO

的事务管理,因为你已经在使用弹簧和@Transactional注释里面,我承担你的春天已经有了一位交易管理者。XML

因此使用Spring的事务管理

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