![](/img/trans.png)
[英]How to catch the DAO Service Layer Exception cleanly in Spring Data JPA
[英]Manual Transactional Service and DAO layer for JPA with Spring
我正在使用 JPA 和 Spring。 如果我讓 Spring 處理事務,那么假設 EntityManager 已正確注入 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();
}
}
}
但是,如果我要手動執行事務,我必須確保將該 EntityManager 的實例傳遞給事務中的每個 DAO。
這是你錯的地方。 來自 Spring 參考, JPA 部分:
這種 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 代理所需要的。
將此添加到您的 spring 配置中
<bean p:entityManagerFactory-ref="emf" class='org.springframework.orm.jpa.support.SharedEntityManagerBean' />
現在您可以在您的 dao 中使用 @Autowired EntityManager
對於事務管理,由於您已經使用 spring 和 @Transactional 注釋,我假設您已經在 spring.Z0F635D0E0F3874FFF8B581C132E6C7A 中聲明了一個事務管理器
所以使用spring的事務管理
作為
transactionStatus = platformTransactionManager.getTransaction(new DefaultTransactionDefinition());
// do your work here
platformTransactionManager.commit(transactionStatus );
我猜有點在黑暗中拍攝,但你知道你可以做到:
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
這通常會消除您希望/需要在具有聲明性事務的系統中使用編程事務的大多數情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.