从 EclipseLink 中隐藏外部实体 类

Hiding foreign entity classes from EclipseLink

我有一个 Java EE web 应用程序和一个用于 Glassfish 4 的自定义领域(身份验证模块)(参见 GlassFish Application Development Guide、II 4-6 "Creating a Custom Realm")。两者都使用JPA,有细微差别。

自定义领域

<persistence-unit name="AuthPU" transaction-type="JTA">
    <jta-data-source>jdbc/AuthDB</jta-data-source>
    <class>auth.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>

申请

<persistence-unit name="AppPU" transaction-type="JTA">
    <jta-data-source>jdbc/AppDB</jta-data-source>
    <class>app.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>

应用程序部署时,抛出异常:

Severe:   javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [AppPU] failed.
Internal Exception: Exception [EclipseLink-7237] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity name must be unique in a persistence unit. Entity name [User] is used for the entity classes [app.User] and [auth.User].

似乎 AppPU 持久性单元以某种方式从 auth.* 包中发现实体(通过 orm.xml?)我不想更改实体名称,因为它会破坏现有的 JPQL 查询。我如何隔离模块以便 AppPU 忽略外部 orm.xml 并且不查看 auth.* 实体包?

P.S。您可能已经注意到,EclipseLink 版本是 2.6.0 - 我已经手动升级了它。 Eclipse 2.5.2GlassFish 4.1 一起提供了相同的异常。

来自 Pro JPA2 这本书

xml-mapping-metadata-complete

When the xml-mapping-metadata-complete element is specified, all annotations in the entire persistence unit will be ignored, and only the mapping files in the persistence unit will be considered as the total set of provided metadata. Only entities, mapped superclasses, and embedded objects that have entries in a mapping file will be added to the persistence unit. .....

<entity-mappings> 
    <persistence-unit-metadata>
         <xml-mapping-metadata-complete/> 
    </persistence-unit-metadata> ...
</entity-mappings> 

将以上内容添加到您的orm.xml。

好的,我知道到底发生了什么。

根据GlassFish Application Deployment Guide (C-13),

the web module follows the standard class loader delegation model and delegates to its parent class loader first before looking in the local class loader.

这是可以使用 glassfish-web.xml<class-loader> 元素控制的默认行为。 EclipseLink 尝试处理它在类路径上找到的 每个 META-INF/orm.xml,因此首先选择自定义领域的那个。即使应用程序的 orm.xml 包含 <xml-mapping-metadata-complete/>,它也不起作用,因为 auth.* 类 已经添加到持久性单元。

问题有两种解决方案(重命名实体除外):

  1. glassfish-web.xml中使用<class-loader delegate="false"/>
  2. 如果以上内容不可接受(“对于网络 访问 EJB 组件或充当 Web 服务客户端的模块 或端点”- 应用程序部署指南),将自定义领域的 META-INF/orm.xml 重命名为其他名称并将其反映在 persistence.xml.