2009-10-18 57 views
5

新春天這裏@stackoverflow春@Transactional合併,堅持問題

我建立一個獨立的庫存&銷售總代理業務跟蹤應用程序(Apache的樞軸/春/ JPA /休眠/ MySQL的) 。

到目前爲止,我認爲一切都是CRUD,所以我打算給所有@Transactional創建一個基類。

然後我遇到了一個問題,我的保存通用方法。 Spring的EntityManager的持久化和合並方法有區別嗎?我試着運行並調用保存插入和更新,它工作正常(我認爲每次我調用我的save方法時,彈簧自動刷新實體//看到記錄的hibernate查詢,是嗎?)。

@Transactional 
public abstract class GenericDAO { 

    protected EntityManager em; 

// em [email protected]/setter 

    public void save(T t) { 
//  if (t.getId() == null) // create new 
//  { 
//   em.persist(t); 
//  } else // update 
//  { 
      em.merge(t); 
//  } 
    } 
} 

順便說一句,有這樣的設置,我不會有太大的妥協表現吧?就像調用salesDAO.findAll()來生成報告一樣(不需要是事務性的,對嗎?)。

謝謝!!!

回答

5

This SO question是一個很好的討論持久與合併,並接受的答案解釋得很好。另一個答案也鏈接到一個很好的博客文章。

根據this other post的第一個回覆,聽起來好像有可能爲保存和更新實體調用合併,但這並不是我已經做到的。在我的Spring/JPA應用程序中,我只需將我的DAO擴展JpaDaoSupport並按以下方式使用getJpaTemplate()。

/** 
* Save a new Album. 
*/ 
public Album save(Album album) { 
    getJpaTemplate().persist(album); 
    return album; 
} 

/** 
* Update an existing Album. 
*/ 
public Album update(Album album) { 
    return getJpaTemplate().merge(album); 
} 
+0

我是客人,這是最簡單的方法。 因此,如果我有JpaDaoSupport,並且從中獲取實體,那麼所有更改都將自動提交? 我想我會有兩種變型的保存方法,一種保持不變,一種調用flush。對此有何評論? – thirdy 2009-10-19 02:07:12

+0

你的意思是在沒有保存或更新的情況下自動執行嗎?如果是這樣,我不這麼認爲,我總是調用保存在一個新的實體或更新現有的實體來堅持。我從來不需要調用flush方法,但是對於任何給定的請求,我的數據庫訪問非常簡單。 – 2009-10-19 03:19:11

+0

我現在不得不放棄嘗試Spring。只是好奇,Grails如何改進呢?我不會在Grails中遇到類似這樣的問題嗎? – thirdy 2009-10-19 13:49:03

4

link其他SO質疑卡萊布發佈確實做到覆蓋的差異和陷阱的一個好工作的堅持()與合併()。然而,我總是用一個save()方法實現我的Dao類,這個方法只調用merge()來處理插入和更新,而我從來沒有遇到任何persist()vs merge()陷阱。

至於效果和交易方法: 上的方法使用@Transactional這是隻讀的操作不會真正影響性能,但是我更喜歡使用的方法級別的註解只是這樣我就可以很容易地分辨哪些方法是更新和這是讀取。您可以通過在@Transactional註釋上設置readOnly屬性來完成此操作。

如果你按照你的方法命名約定(即任何read方法總是getXXX開始),你也可以使用poincut語法在Spring配置文件來自動進行這種分化:

<tx:advice id="txAdvice" transaction-manager="txManager"> 
    <tx:attributes> 
     <tx:method name="get*" read-only="true"/> 
     <tx:method name="*"/> 
    </tx:attributes> 
    </tx:advice> 

Spring documentation on Transactions欲瞭解更多信息。

此外,我通常把@Transactional屬性放在我的Dao類的上一層,在服務層。 Dao類的方法對於每個方法調用都是不同的數據庫操作,而服務方法可以爲一系列更新執行一次提交/回滾。

+0

感謝您的回答。我想我會堅持純粹的JPA,(我沒有太多的靈活性) – thirdy 2009-10-19 13:50:26