2009-11-23 36 views
8

我們正在使用JPA + Spring + EJB的Toplink實現。在我們的一個EJB中,我們有這樣的東西:JPA - 保存更改不會持續()調用

public void updateUser(long userId, String newName){ 
    User u = em.get(User.class, userId); 
    u.setName(newName); 
    // no persist is invoked here 
} 

所以,基本上這個updateUser方法應該更新給定id的用戶名。 但是這個方法的作者忘了調用em.persist(u);

而最奇怪的是,它工作正常。怎麼會這樣?我百分之百地確信 沒有調用em.persist()或em.merge(),但沒有辦法將更改保存到數據庫中。他們可以嗎?有沒有這種情況發生的情況?

感謝

回答

11

你是一個管理實體的工作。如果實體由於其實體管理器關閉而未被分離,則在刷新/關閉會話並提交事務時,對實體所做的所有更改都會反映到數據庫中。

Java EE tutorial

持久實體的狀態被 同步到數據庫時 交易與該實體是 相關聯的提交。

清楚和解釋編輯:那麼有三種不同的模式,一個實體可以其生命週期內是:

  • 未保存:實體已被實例化,但persist()還沒有被稱爲尚未。
  • 管理:實體已使用persist()持久保存,或從數據庫加載,並與實體管理器會話相關聯。實體管理器會話刷新時,實體的所有更改都會反映到數據庫中。
  • 分離:實體的實體經理會話已關閉。對實體的更改不會自動反映到數據庫,但可以使用merge()命令明確合併。
+0

謝謝。這非常有幫助!我一直認爲調用em.persist()是必需的,即使對象與當前的EntityManager關聯。 – anthony 2009-11-24 18:21:42

+0

奇怪:在我的設置中,我有一個託管實體的參考。然後我改變這個實體的狀態。然後我調用'entityManager.flush()'。如果這是在事務內運行,那麼實體的更改狀態**將寫入**到數據庫。在沒有事務的情況下運行,那麼實體的更改狀態**不會寫入**到數據庫。所以下面的語句是真的嗎?:*「爲了將最新狀態的'obj'寫入數據庫,總是必須有一個事務提交或一個'entityManager.persist(obj)'調用。」* ....(我在Hibernate(4.1.7.Final)中使用JPA 2.0) – Abdull 2013-02-13 16:53:22

+0

@Abudull,是的,JPA規範沒有定義任何自動提交行爲,所以你需要一個正在進行的事務或根本沒有任何東西被寫入數據庫。 – Henning 2013-02-13 18:37:14