2011年3月29日 星期二

EntityManager 與 Entity

[EntityManager]

* JPA中要對資料庫進行操作前,必須先取得EntityManager實例,這有點類似JDBC在對資料庫操作之前,必須先取得Connection實例,EntityManager是JPA操作的基礎,它不是設計為執行緒安全(Thread-safe)。

* EntityManager主要在管理Entity實例生命週期,透過EntityManager,對Entity實例的操作,可以對應至資料庫進行新增、查找、修改、刪除、重清等動作

* 新增: 使用 EntityManager 的 persist(),這也會讓Entity實例處於Managed狀態,ex:
User user = new User(); // 設定 user 相關屬性
entityManager.persist(user);

* 若要取得資料表中的資料: 使用EntityManager的 find(),指定主鍵物件與Class實例來取得對應的資料並封裝為物件,查找回的物件會處於Managed的狀態,ex:
User user = entityManager.find(User.class, id);

* 若資料庫中已有對應資料,則要修改資料有幾種方式:
  • 若物件是在Managed狀態,例如查找物件之後,直接更新物件,在交易確認之後,物件的更新就會反應至資料表之中:
User user = entityManager.find(User.class, id);
user.setName("Justin Lin");
  • 若物件是在Detached狀態
    • 可使用EntityManager的 merge() 將物件轉至生命周期的Managed狀態,合併物件上之變更:
// 若 user 狀態有所變動
entityManager.merge(user);
    • 或先使用merge()方法將Detached狀態的Entity實例轉至Managed的狀態,再更新物件,在交易確認之後,物件的更新就會反應至資料表之中:
User user1 = entityManager.merge(user);
user1.setName("Justin Lin");

* 刪除資料表中的資料
  • 物件必須是在Managed的狀態,ex:
    • 用EntityManager的find()方法查找物件,以查找到的物件配合remove()方法來移除
    • 或是使用merge(()方法將Entity處於Managed狀態再用remove()移除,移除之後,物件對應不到資料表格中實際的資料,處於Removed狀態:

User user = entityManager.find(User.class, id);
entityManager.remove(user);

* refresh(): 若在載入某個Entity實例之後,而資料表格因另一個操作而發生變動,可以使用此方法,將資料表格的更動載入Entity實例中。

* flush(): 強制EntityManager中管理的所有Entity對應的資料表格與Entity的狀態同步。

* clear(): 可以將EntityManager所管理的Entity實例清除,使Entity處於Detached狀態。

* Persistence Context
  • 預設為Transaction-scoped:
    • 在EntitySessionBean方法開始前會起始交易,結束後停止交易
    • Persistence Context的存活範圍在交易之間,也就是Entity實例在交易完成之後,將會不受EntityManager的管理,將不在是Managed狀態,而處於Detached狀態
  • 每個EntityManager都與一個 Persistence Context 關聯。
  • EntityManager不直接維護Entity,而是將之委托給Persistence Context,Persistence Context中會維護一組Entity實例。
  • 每個Entity在Persistence Context為Managed狀態,Entity實例會有Managed、Detached、Removed狀態。

* 可以在使用@PersistenceContext時,指定type屬性為PersistenceContextType.EXTENDED(預設為PersistenceContextType.TRANSACTION), 使Persistence Context為Extended Persistence Context,在EntityManager實例存活期間,Entity始終受到PersistenceContext的管理,Extended Persistence Context只能用於Stateful Session Bean中,Entity會一直受EntityManager的PersistenceContext管理,直到Stateful Session Bean結束而EntityManager關閉(close)為止。

* 可以想像指定type屬性為PersistenceContextType.EXTENDED 時,一旦進入EntityManager的管理,Entity一直處於Managed的狀態

* Application-Managed EntityManager,則其行為類似於以上說明的Extended-scoped EntityManager,也就是Persistence Context是隨著EntityManager的關閉而失效,也就是當EntityManager關閉後,Entity就不再為Managed狀態。


* Reference
- EJB3 Gossip: 使用 EntityManager
- EJB3 Gossip: Entity 生命週期
- EJB3 Gossip: EntityManager 範圍

沒有留言:

張貼留言