我将ServiceMix与Apache Felix一起使用,而我的企业应用程序包含多个捆绑包。例如,我有一个包含我的jpa实体类的包和另一个包含业务逻辑和dao-classes的包。由于我使用OpenJPA,实体包项目需要META-INF文件夹中的persistenc.xml用于在编译时注入字节码,但是此包通过包清单中的Meta-Persistence头提供持久性单元。 在dao提供包中,我使用blueprint.xml注入实体管理器:
<bean id="systemUserDAOBean" class="server.daos.SystemUserDAO">
<tx:transaction method="*" value="Required" />
<jpa:context property="entityManager" unitname="mypu" />
</bean>
如果我在运行时调用dao的以下方法:
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返回对象的类的类加载器与加载该方法的返回类型的类加载器不同。也许第一个类加载器是实体包的类加载器,第二个类加载器是dao提供包的类加载器?!
如果我将persistence.xml复制到DAO-Bundle并在blueprint.xml中使用其持久性单元,则不会抛出ClassCastException。但在这种情况下,我在同一个应用程序中有两个相同的persistence.xml文件,我不想要的。 :(
有没有人知道如何解决这个问题?
谢谢你,Phill
编辑:当我重新启动servicemix时,异常消失,直到我更新持久性捆绑包。我发现,两个类加载器都来自持久化包。
答案 0 :(得分:0)
听起来您已将域类(包括,我认为,SystemUser
)复制到多个包中。你不应该这样做,因为正如你所发现的那样,Java认为不同的ClassLoader加载的同一个类是不同的类,因此你得到了ClassCastException
。
您应该使用Export-Package
标头从一个捆绑包中导出域包。可能这应该从您的持久性捆绑包中完成。所有其他捆绑包都应该导入该包。