2016-03-17 52 views
0

鑑於兩行代碼:JPA - Hibernate Session被關閉,但EntityManager的工作

entityManager.find(MyEntity.class, myId); 

((Session) getEntityManager().getDelegate()).load(MyEntity.class, myId); 

第一條指令工作正常,但第二個罰球org.hibernate.SessionException:會話被關閉!任何想法 ?

語境:春季批次3.0.6/3.5.0冬眠

信息:EntityManager的注入:

@PersistenceContext 
protected EntityManager entityManager; 

更新1

我可以在查找方法的調用見到this.getSession(),如果會話爲空,則打開新會話(在EntityManagerImpl.getRawSession中)

更新2

在第二種情況中的getSession方法不叫,但一類叫做SharedEntityManagerCreator是關閉會話:

if(isNewEm) { 
    EntityManagerFactoryUtils.closeEntityManager(target1); 
} 
+0

你是否在同一個流程中逐一調用上述兩行?如果你交換它們會發生什麼? –

+0

我的目標是僅使用hibernate會話,因爲我需要Query類的滾動方法。所以這是一個簡單的測試。我在不同的測試用例中運行每條指令。 – fego

回答

1

有了適當的JPA事務管理底層的Hibernate Session應該已經打開。如果您使用聲明式事務管理(基礎事務管理器應該是JPA認識的),請確保您使用@Transactional註釋了服務方法。如果您不使用聲明式事務管理,你可以調用

entityManager.getTransaction().begin(); 

不要忘了,當你完成與commit()rollback()關閉交易。

+0

謝謝你的回答。我正在使用spring批處理,並且我在Reader中。交易應該是開放的,不是嗎?也許在這種情況下,會話不會自動打開。當我查看JpaPagingItemReader的代碼時,我可以看到EntityManager的生命週期是句柄是讀者。 – fego

+0

我不熟悉Spring Batch。讓所有數據庫操作都使用事務是一種很好的做法,即使是隻讀的,因爲這樣,至少您可以獲得數據庫的一致視圖,具體取決於您的隔離級別。 –

相關問題