Persistence Context


PersistenceContext 是個由 EntityManager 管理的集合物件,其管理一堆Entity實例,Entity在PersistenceContext的Persistence scope管理期間為Managed狀態。

若為Container-Managed EntityManager,可透過@PersistenceContext 的type來設定PersistenceContext的存活範圍為以交易為範圍,或是為延伸範圍,若為Application-Managed EntityManager,則PersistenceContext存活範圍在EntityManager建立與關閉之間,這 在 EntityManager& nbsp;範圍 有 說明。

PersistenceContext管理的Entity為Managed狀態,基本上此時你對Entity實例的任何屬性變動, PersistenceContext都會將之對應至資料庫的變動,不過每次在程式中一旦變動Entity就作資料庫IO會有效能議題,因此實際上對 Entity的變動,不會馬上反應出資料庫中,而是會等到EntityManager作了flush()之後,在這之前對Entity的變動,會被收集起 來,再一次進行資料庫的變更。

EntityManager的flush()執行時機可能在:
  • flush()的FlushModeType預設是AUTO時:
    • 如果是Transaction-scoped EntityManager,在交 易確認時會flush()。
    • 如果是Extended-scoped EntityManager,或者Application-Managed EntityManager,則是在EntityManager關閉時flush()。
  • 如果查詢某個實體前,該實體有變動,則會先flush()再進行查詢。
  • 主動呼叫EntityManager的flush()方法。

可以使用EntityManager的setFlushMode()設定FlushModeType, 預設是FlushModeType.AUTO, 可以設定為FlushModeType.COMMIT,則只有在您主動確認一個交易,才會進行 flush(),如果您設定FlushModeType.COMMIT,在查詢資料之前若 Entity有變動,則您要主動flush(),再進行查詢,才不致查詢到舊資料。

由於PersistenceContext的Persistence Scope存活期間會管理Entity,所以在大量儲存物件時,PersistenceContext 中管理的Entity實例會不斷的增加,甚至最後導致OutOfMemoryError,可 以主動每隔一段時間使用EntityManager的flush()強制同步Entity與資料庫,再使用clear()清除 PersistenceContext中管理的Entity實例。