【问题标题】:OSGi using jpa persistence unit from another bundle?OSGi 使用来自另一个包的 jpa 持久性单元?
【发布时间】:2013-11-27 19:12:29
【问题描述】:

我将 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

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

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

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

谢谢你,菲尔

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

【问题讨论】:

    标签: java jpa osgi openjpa blueprint


    【解决方案1】:

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

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

    【讨论】:

    • 不,没有复制的课程。只是我的“持久性捆绑包”提供了所有实体类(通过导出包)。
    • 抱歉,我无法提供任何进一步的建议,只能继续寻找该重复项。当您看到错误“ClassCastException: X cannot be cast to X”时,它总是意味着类 X 已由两个不同的类加载器分别加载(在 Java 中,类的标识是它的组合完全限定名称加载它的类加载器)。
    猜你喜欢
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2014-06-25
    • 2011-11-30
    • 2012-09-25
    • 2012-08-10
    相关资源
    最近更新 更多