Java 使用Spring为JPA提供手动事务服务和DAO层

Java 使用Spring为JPA提供手动事务服务和DAO层,java,hibernate,spring,jpa,transactions,Java,Hibernate,Spring,Jpa,Transactions,我将JPA与Spring一起使用。如果让Spring处理事务,那么假设EntityManager已正确注入DAO中,我的服务层就是这样的: MyService { @Transactional public void myMethod() { myDaoA.doSomething(); myDaoB.doSomething(); } } 但是,如果要手动执行事务,则必须确保将EntityManager实例传递到事务中的每个DAO中。你知道如何更

我将JPA与Spring一起使用。如果让Spring处理事务,那么假设EntityManager已正确注入DAO中,我的服务层就是这样的:

MyService {

   @Transactional
   public void myMethod() {
       myDaoA.doSomething();
       myDaoB.doSomething();
    }
}
但是,如果要手动执行事务,则必须确保将EntityManager实例传递到事务中的每个DAO中。你知道如何更好地重构它吗?我需要做新的MyDaoA(em)或者像doSomething(em)一样将它们传递到每个DAO方法中


我想是在黑暗中拍摄的,但你知道你能做到:

这通常消除了您希望/需要在具有声明性事务的系统中使用编程事务的大多数情况

然而,如果我要做交易 手动操作,我必须确保通过 EntityManager的实例进入 事务中的每个DAO

这就是你错的地方。从Spring引用中,:

这种DAO的主要问题是 它总是创造一个新的 整个工厂的整体经理<斯特朗>你 可以通过请求 事务实体管理器 称为“共享实体管理器”,因为 它是一个共享的线程安全代理 实际事务 EntityManager)将改为注入 工厂名称:

@PersistenceContext
注释已被删除 一个可选的属性类型,它 默认为 PersistenceContextType.TRANSACTION。 这个默认值是您需要修改的 接收共享的EntityManager代理


将其添加到spring配置中

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

我还不清楚如何使用服务和DAO层进行手动事务。a)如果必须这样做,我可能会使用TransactionTemplate或JpaTemplate b)不要这样做。这很痛苦。对不起,这远远超出了这个问题的范围。阅读Spring参考资料,特别是事务管理和ORM部分(提示:异常翻译是您的朋友)
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(); 
    }
}
<bean p:entityManagerFactory-ref="emf" class='org.springframework.orm.jpa.support.SharedEntityManagerBean' />
transactionStatus = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
// do your work here 
platformTransactionManager.commit(transactionStatus );