隐藏EclipseLink中的外部实体类

时间:2015-04-24 11:04:34

标签: java jpa glassfish eclipselink

我有一个Java EE Web应用程序和Glassfish 4的自定义领域(身份验证模块)(参见GlassFish Application Development Guide,II 4-6“创建自定义领域”)。他们两个都在使用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>
  • auth.User是一个包含特定于身份验证的数据的技术实体
  • EntityManager是使用Persistence API创建的(因为没有可用于域的注入)
  • META-INF/orm.xml用于定义映射(根本没有@Entity注释)
  • 该模块打包为JAR并部署到$GLASSFISH_HOME/glassfish/domains/domain1/lib

应用

<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>
  • app.User是一个商业实体
  • EntityManager注入@PersistenceContext
  • 使用@Entity个注释(用于基本映射) META-INF/orm.xml文件(用于自定义)
  • 应用程序以标准方式打包和部署。

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

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.2附带的GlassFish 4.1也提供了相同的例外情况。

2 个答案:

答案 0 :(得分:1)

好的,我已经弄清楚到底发生了什么。

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

  

Web模块遵循标准类加载器   委托模型和委托给它的父类加载器之前   看着当地的班级装载机。

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

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

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

答案 1 :(得分:0)

来自Pro JPA2一书

  

<强> XML映射元数据完成

     

指定xml-mapping-metadata-complete元素时,全部   整个持久性单元中的注释将被忽略,并且仅被忽略   持久性单元中的映射文件将被视为   提供的元数据的总集合。 仅实体,映射的超类,   将添加在映射文件中具有条目的嵌入对象   持久性单位。 .....

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

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