2013-07-17 168 views
42

我有一個EJB,用於將對象保存到數據庫。在我看到的一個例子中,一旦保存了這些數據(EntityManager.persist),就會調用EntityManager.flush();爲什麼我需要這樣做?我保存的對象沒有附加,並且稍後在方法中不使用。事實上,一旦保存方法返回,我會期待資源被釋放。 (該示例代碼執行此上一個刪除呼叫爲好。)EntityManager.flush是做什麼的,爲什麼我需要使用它?

if (somecondition) 
     entityManager.persist(unAttachedEntity); 
    else 
    { 
     attachedEntityObject.setId(unAttachedEntity.getId()); 
    } 
    entityManager.flush(); 

回答

32

EntityManager.flush();的呼叫將迫使數據是長期存在於數據庫立即作爲EntityManager.persist()不會(取決於EntityManager的是如何配置的:FlushModeType (AUTO或COMMIT),默認情況下它被設置爲AUTO,並且如果它被設置爲COMMIT,則會自動完成刷新,當事務被提交時,數據的潛力將延遲到底層數據庫)。

+5

對FlushModeType的描述不正確:基本上AUTO意味着如果你改變了一個實體,然後做了一個可能返回該實體的SELECT查詢,那麼AUTO將強制在SELECT執行之前刷新該實體的改變。 –

14

EntityManager.persist()使實體持久化,而EntityManager.flush()實際上在數據庫上運行查詢。

因此,當您撥打EntityManager.flush()時,將在數據庫中執行插入/更新/刪除關聯實體的查詢。任何約束失敗(列寬,數據類型,外鍵)此時都是已知的。

具體行爲取決於flush-mode是AUTO還是COMMIT。

13

可以使用EntityManager.flush()操作在事務提交之前將所有更改寫入數據庫。默認情況下,在事務提交之前,JPA通常不會將更改寫入數據庫。這通常是可取的,因爲它避免了數據庫訪問,資源和鎖定,直到需要爲止。它還允許對數據庫寫入進行排序,並進行批處理以實現最佳數據庫訪問,並保持完整性約束並避免死鎖。這意味着當您調用持久化,合併或刪除數據庫時,DML INSERT,UPDATE,DELETE不會執行,直到提交或直到刷新被觸發爲止。

+1

可以使用EntityManager.flush()操作在事務提交之前將所有更改寫入數據庫。 - >這不完全正確。您仍然需要提交,flush僅在沒有提交的情況下將SQL語句發送到數據庫。觸發刷新,無需提交仍然不會實際插入任何實體。如果你沒有刷新,commit會刷新,但是flush不會提交。 –

+0

EntityManager.flush()會把數據發送到數據庫,但是在這一點上它不會被其他人看到。相反,已更改的數據庫條目將獲得行鎖定。但是隻有在commit()之後,這些更改才能被其他人看到,並且鎖被刪除。 – user2081279

8

因此,當您撥打EntityManager.persist()時,它只會讓實體得到由EntityManager的管理,並將它(實體實例)添加到Persistence Context。明確flush()將使現在位於Persistence Context中的實體移動到數據庫(使用SQL)。

如果沒有使用flush()方法,那麼在將此Persistence Context所關聯的事務提交時,會將此事件(將實體從Persistence Context移動到數據庫)發生。

相關問題