2011-04-28 157 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);