獲取EntityManager避免IllegalStateException: EnityManager is closed

在使用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;
  • ➊ 這裏須要一個entityManager。

之前看hibernate的官方文檔時總感受其不太友好,不少代碼都只給了一部分,並無給出整個的上下文。好比這裏的entityManager。後來才明白原來用戶在使用hibernate時都會有本身特定的環境,而每一個特定環境都有着獲取entityManager的不一樣方式,官方在這裏是想告訴咱們:這裏須要一個entityManager,至於該entityManager你如何獲取,取決於用戶當前的特定環境。spring

spring boot中獲取entityManager

spring boot中能夠很是簡單的獲取entityManager:springboot

@Autowired  
private EntityManager entityManager;

但若是直接將此對象放到AuditReaderFactory.get(entityManager);➊ 中使用,則會面臨如下問題:this

  • 第一次使用時正常。
  • 第二次使用時報如下錯誤:IllegalStateException: EnityManager is closed

這時因爲:每一個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的異常。對象

相關文章
相關標籤/搜索