OSGi使用另一个捆绑的jpa持久性单元?

时间:2013-11-14 16:43:11

标签: java jpa osgi openjpa blueprint

我将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时,异常消失,直到我更新持久性捆绑包。我发现,两个类加载器都来自持久化包。

1 个答案:

答案 0 :(得分:0)

听起来您已将域类(包括,我认为,SystemUser)复制到多个包中。你不应该这样做,因为正如你所发现的那样,Java认为不同的ClassLoader加载的同一个类是不同的类,因此你得到了ClassCastException

您应该使用Export-Package标头从一个捆绑包中导出域包。可能这应该从您的持久性捆绑包中完成。所有其他捆绑包都应该导入该包。