2016-03-02 21 views
0

我的工作從休眠/ OpenEJB的/ TomEE的應用遷移到Hibernate/JBoss和我有這樣的例外在運行時:爲什麼EntityManager的getDelegate()方法在Hibernate中不會返回EntityManagerImpl作爲底層對象?

java.lang.ClassCastException: org.hibernate.internal.SessionImpl cannot be cast to org.hibernate.ejb.EntityManagerImpl 

雖然運行此代碼:

... 
import javax.persistence.EntityManager; 
... 
@PersistenceContext(...) 
protected EntityManager em; 
... 
EntityManagerImpl hibernateEntityManagerImpl = (EntityManagerImpl)em.getDelegate(); 
Session sess = hibernateEntityManagerImpl.getSession(); 
... 

同代碼在TomEE中運行。我不知道爲什麼getDelegate()方法不會將EntityManager作爲基礎對象返回。

NB:

  • 應用程序已經使用Hibernate(有lawer版)之前,我只是將其遷移到JBoss;
  • 我使用Hibernate的4.2.21.Final(同一版本的EntityManager);
  • 的persistence.xml提供商org.hibernate.ejb.HibernatePersistence

感謝您的幫助。

+0

@NeilStockton:我糾正了我的言論。該應用程序已經與休眠,我正在遷移到JBoss。 –

+0

僅供參考 - 檢查[JBoss Windup遷移工具](https://github.com/windup/windup/wiki)。 –

+0

什麼版本的JBoss EAP? –

回答

1

如果您正在使用的JBoss EAP/Hibernate的工作,可以更換

EntityManagerImpl hibernateEntityManagerImpl = (EntityManagerImpl)em.getDelegate(); 

通過:

org.hibernate.Session sess = (Session) em.getDelegate(); 
+0

我已經使用你的解決方案,它的工作原理:D。對於新應用程序更好的解決方案是'final org.hibernate.Session sess = this.em.unwrap(org.hibernate.Session.class); '。但我想明白爲什麼會處理這個異常!它爲什麼適用於TomEE而不是JBoss! –

0

請注意,getDelegate方法實現特定的提供者。對於一家提供商而言,有效的方式並不一定適用於另一家提供商。 這裏是說的javadoc爲EntityManager的約getDelegate()

返回底層提供的對象,如果 可用。此方法的結果是特定於實現的。

JPA規範說明什麼是提供者的必需條件,什麼不是。 jpa規範中的「非強制性」事件將由jpa提供者執行或不執行。

這是更好,因爲我們的目標是減少供應商的JPA從依賴只使用強制性規範的JPA。我們不應該使用提供者特定的實現。

+0

在Walid的例子中,他使用了相同的提供者Hibernate,這讓人驚歎,所以我不能解釋爲什麼它在tomEE上運行而不是在Jboss上運行。你可以給我更多的信息請 – Kikou

0

你沒有告訴你使用哪種的JBoss EAP的版本,所以我以爲這是最新的。

的JBoss EAP/JBoss的AS/WildFly捆綁它自己的JBoss Hibernate的。如果您的應用程序中捆綁了另一個Hibernate庫,則基於類加載配置,應用程序的類加載器可能會使用它,也可能不會使用它。

如果你的應用是基於Maven的時候,你應該遵循JBoss的開發者指南。檢查JBoss Quickstarts並相應地修改你的pom。這真的很值得,並且會爲您節省很多問題。

最後,儘量避免使用專有的API。每次你重新輸入一個特定實現的接口,你都可能使用一個專有的API並尋求麻煩。

相關問題