2013-11-14 80 views
0

我使用ServiceMix和Apache Felix,我的企業應用程序由幾個軟件包組成。例如,我有一個包含我的jpa實體類和另一個包含業務邏輯和道教類的包。由於我使用OpenJPA,因此entity-bundle項目需要在編譯時注入字節碼的META-INF文件夾中的persistenc.xml文件,但是該包通過包清單中的元持久性標頭提供了持久性單元。 裏面的DAO提供捆綁的我用blueprint.xml注入實體管理器:OSGi使用jpa持久性單元從另一個捆綁?

<bean id="systemUserDAOBean" class="server.daos.SystemUserDAO"> 
    <tx:transaction method="*" value="Required" /> 
    <jpa:context property="entityManager" unitname="mypu" /> 
</bean> 

如果我叫在運行時道的方法如下:

public SystemUser readSystemUser(String username) { 
     final EntityManager em = getEntityManager(); 
     final Query q = em.createQuery("select a from SystemUser a where a.username = '"+username+"'"); 
     return (SystemUser) q.getSingleResult(); 
} 

一個拋出ClassCastException:

java.lang.ClassCastException:mypackage.SystemUser不能轉換到mypackage.SystemUser

我到目前爲止發現的是,加載了entitymanager返回對象的類的類加載器與加載該方法的返回類型的類加載器不同。也許第一個類加載器是實體包的類加載器,第二個是類提供包的類加載器?!

如果我將persistence.xml複製到DAO-Bundle並在blueprint.xml中使用其持久性單元,則不會拋出ClassCastException。但在這種情況下,我在同一個應用程序中有兩個相同的persistence.xml文件,我不想要。 :(

沒有任何人有一個想法如何解決這個問題

謝謝你,菲爾

編輯:當我重新啓動ServiceMix的異常消失了,直到我更新的持久性捆綁包我找到了。 ,這兩個類加載器都來自持久性包

回答

0

聽起來好像你已經將域類(包括我假設的SystemUser)複製到多個bundle中,你不應該這樣做,因爲正如你發現的那樣,Java認爲相同的類由不同的ClassLoaders加載成不同的類,因此你得到ClassCastException

您應該使用Export-Package標題從一個包導出域包。可能這應該通過持久性包來完成。所有其他軟件包都應該導入該軟件包。

+0

不,沒有複製的類。只是我的「持久性束」提供了所有的實體類(通過Export-Package)。 –

+0

對不起,我不能提供任何進一步的建議,除非繼續尋找重複。當你看到錯誤「ClassCastException:X不能轉換爲X」時,它總是*表示類X已經被兩個不同的類加載器單獨加載(在Java中,類的標識是其完全限定名*和*加載它的類加載器)。 –