0

我将 ServiceMix 与 Apache Felix 一起使用,我的企业应用程序由几个捆绑包组成。例如,我有一个包含我的 jpa 实体类的包和另一个包含业务逻辑和 dao 类的包。因为我使用 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

到目前为止我发现的是,加载实体管理器返回对象的类的类加载器与加载方法的返回类型的类加载器不同。也许第一个类加载器是实体包的类加载器,第二个是dao提供包的类加载器?!

如果我将 persistence.xml 复制到 DAO-Bundle 并在 blueprint.xml 中使用其持久性单元,则不会抛出 ClassCastException。但在这种情况下,我在同一个应用程序中有两个完全相同的 persistence.xml 文件,这是我不想要的。:(

有谁知道如何解决这个问题?

谢谢你,菲尔

编辑:当我重新启动 servicemix 时,异常消失了,直到我更新持久性捆绑包。我发现,这两个类加载器都来自持久性捆绑包。

4

1 回答 1

0

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

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

于 2013-11-14T20:02:07.027 回答