應用程序管理的EntityManager(Application-Managed EntityManager)
Ø
在JavaSE和JavaEE環境下建立應用程序管理的EntityManager的不一樣之處,並不是建立EntityManager的方式不一樣,而是得到建立EntityManager的EntityManagerFactory的方式不一樣。
ü
JavaSE
環境:Persistence.createEntityManager(「APU」).createEntityManager();
ü
JavaEE
環境:使用@PersistenceUnit(unitName=」APU」)標註EntityManagerFactory屬性。而後經過調用emf.createEntityManager()得到EntityManager。因爲EntityManager是開發者顯式建立並管理的,所以須要在用完以後調用em.close()方法將之關閉。EntityManagerFactory是容器注入的,不須要也不該該調用emf.close()方法。
Ø
在JavaSE環境下,Persistence類有兩個重載的createEntityManagerFactory()方法:
ü
有一個參數:該參數表示PersistenceUnit的名字,而後使用persistence.xml中的屬性建立一個EntityManagerFactory。
ü
有兩個參數:第一個參數的做用同上,第二個參數可讓開發者設置額外的一些屬性,能夠做爲persistence.xml中屬性的擴充,若是屬性的鍵與persistence.xml中相同,則代碼中的設置覆蓋persistence.xml中的配置值。
Ø
就持久化上下文而言,應用程序管理的EntityManager就像擴展的容器管理的EntityManager。當建立應用程序管理的EntityManager實例以後,該EntityManager實例當即建立一個屬於它本身私有的持久化上下文,該持久化上下文將一直存活下去,直到所屬的EntityManager實例銷燬才消失。
4. 容器管理的事務 之 容器管理的持久化上下文
Ø
JPA
支持兩種事務類型:
ü
本地資源事務(RESOURCE_LOCAL):使用JDBC驅動管理的本地事務。
ü
Java
事務API(JTA):可用於管理分佈式事務,管理多數據源的狀況。
ü
容器管理的EntityManager老是使用JTA事務。應用程序管理的EntityManager可使用本地資源事務,也可使用JTA事務。
ü
在JavaSE環境下,默認的事務類型是RESOURCE_LOCAL,而在JavaEE環境下,默認的事務類型是JTA。
ü
事務類型在persistence.xml中定義。
Ø
只能有一個持久化上下文與JTA關聯,而且只能有一個持久化上下文在事務中傳播。
Ø
對於容器管理的EntityManager,在同一事務中必須使用相同的持久化上下文。
Ø
事務範圍內的持久化上下文:事務範圍內的持久化上下文將其生命週期綁定到某個事務,在須要的時候,事務範圍內的持久化上下文由事務範圍內的EntityManager負責建立,之因此說「在須要的時候」,是由於事務範圍內的持久化上下文是「懶加載」的,只有在EntityManager實例調用相關的數據訪問方法而且當前不存在可用的持久化上下文的時候,纔會建立持久化上下文。
Ø
擴展的持久化上下文:擴展的持久化上下文與有狀態會話Bean綁定。不一樣於事務範圍內的持久化上下文爲每個事務建立一個新的持久化上下文,有狀態會話Bean中擴展的EntityManager老是使用相同的持久化上下文。有狀態會話Bean老是隻和一個持久化上下文綁定,而且在有狀態會話Bean建立時建立該持久化上下文,在有狀態會話Bean銷燬時註銷該持久化上下文。也就是說,不一樣於事務範圍內的持久化上下文,擴展的持久化上下文不是「懶加載」的。
Ø
持久化上下文的衝突:當調用某個方法時有若干個持久化上下文,則會出現持久化上下文衝突,拋出異常。有個特殊狀況,即在一個有狀態會話Bean的擴展持久化上下文中調用另外一個有狀態會話Bean的方法,而且被調用的會話Bean也使用擴展持久化上下文,這樣當調用被調用的會話Bean中方法時雖有兩個持久化上下文可用,但並不會出現衝突。被調用的會話Bean繼承調用者的持久化上下文。