在使用springboot進行一些非封裝的JPA操做時,咱們可能須要EntityManager
的支持。好比筆者近期啓用了hibernate envers
來記錄某個數據表的數據變動狀況,在進行數據查詢時參閱了官方文檔的如下代碼:java
AuditReader reader = AuditReaderFactory.get(entityManager); ➊ Person person2\_rev1 = reader.find(Person.class, person2.getId(), 1); assert person2\_rev1.getAddress().equals(new Address("Grimmauld Place", 12)); Address address1\_rev1 = reader.find(Address.class, address1.getId(), 1); assert address1\_rev1.getPersons().getSize() == 1;
之前看hibernate的官方文檔時總感受其不太友好,不少代碼都只給了一部分,並無給出整個的上下文。好比這裏的entityManager
。後來才明白原來用戶在使用hibernate時都會有本身特定的環境,而每一個特定環境都有着獲取entityManager
的不一樣方式,官方在這裏是想告訴咱們:這裏須要一個entityManager
,至於該entityManager
你如何獲取,取決於用戶當前的特定環境。spring
在spring boot
中能夠很是簡單的獲取entityManager
:springboot
@Autowired private EntityManager entityManager;
但若是直接將此對象放到AuditReaderFactory.get(entityManager);
➊ 中使用,則會面臨如下問題:this
這時因爲:每一個entityManager
只可以用一次,用完之後該entityManager
便會自動關閉,因此當第二次再用的時候便發生了EnityManager is closed的錯誤。hibernate
正確的方法以下:code
@Autowired private EntityManager entityManager; ... EntityManager tempEntityManager = this.entityManager.getEntityManagerFactory().createEntityManager(); AuditReaderFactory.get(tempEntityManager);
這樣以來,在第一次須要entityManager
時,咱們從工廠中建立一個臨時的tempEntityManager
,在查詢完畢後系統自動關閉了這個臨時的tempEntityManager
;下次查詢時,咱們再獲取一個全新臨時tempEntityManager
,從而保障了屢次調用該方法,也不會出現EnityManager is closed的異常。對象