JPA 2.0:自动将实体类*从不同的 jar* 添加到 PersistenceUnit

Posted

技术标签:

【中文标题】JPA 2.0:自动将实体类*从不同的 jar* 添加到 PersistenceUnit【英文标题】:JPA 2.0: Adding entity classes to PersistenceUnit *from different jar* automatically 【发布时间】:2011-09-16 20:48:41 【问题描述】:

我有一个基于 Maven 构建的基于 CDI 的 Java SE 应用,它有一个 core 模块和其他模块。 核心有persistence.xml 和一些实体。 模块有额外的实体。

如何将实体添加到持久化单元的聚光灯下?

我已阅读 Hibernate 手册,http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html#setup-configuration-packaging

我也看过这些 SO 问题

How can I merge / extend persistence units from different JARs? define jpa entity classes outside of persistence.xml Programmatically loading Entity classes with JPA 2.0?

我正在寻找一种解决方案,Hibernate 将扫描所有已加载的类,或者从其他 jar 中获取一些配置文件(例如 CDI 对 beans.xml 所做的)。

我的应用不使用 Spring。 我不坚持可移植性——我会坚持使用 Hibernate。

有这样的解决方案吗? 有没有办法从 persistence.xml 创建一个 PU 并以编程方式向其中添加类? @Entity 类创建后可以添加到EntityManagerFactory 吗?

更新:我在org.​hibernate.​ejb.​Ejb3Configuration找到:

public Ejb3Configuration configure(String persistenceUnitName, Map integration)  

http://docs.jboss.org/hibernate/entitymanager/3.6/javadocs/

【问题讨论】:

也许这可能是一个解决方案:***.com/questions/15026302/… 【参考方案1】:

我遇到了同样的问题,不幸的是没有简单的解决方案,基本上看起来 JPA 并不是为这种方式设计的。一种解决方案是每个***项目(应用程序)只有 一个 persistence.xml。它有点类似于 log4j 配置。 persistence.xml 必须列出应用程序使用的所有类(使用<class>),或者,如果它不是Java SE 应用程序,则列出应用程序使用的jar 文件(使用<jar-file>)。这样,您可以将来自多个模块(jar)的实体放入单个持久性单元中。缺点很明显:您必须在一个文件中列出所有内容。

编辑:我(可能)找到了另一个使用 XML 映射文件的解决方案,请在此处查看:Multiple jars, single persistence unit solution?

【讨论】:

【参考方案2】:

可能重复,请参阅my SO question。

我们遇到了同样的问题,我们发现的唯一方法是将所有实体累积在一个 persistence.xml 中,用于最终的(网络)应用程序。

同时,我们在测试资源中定义了单独的 persistence.xml 文件,以便我们可以针对每个模块运行验收测试。

【讨论】:

【参考方案3】:

有几种方法可以解决:

    如Do I need <class> elements in persistence.xml? 中所述,您可以设置hibernate.archive.autodetection 属性,Hibernate 应该能够从类路径中查找所有带注释的类。但是,这不符合 JPA 规范。

    1234563带注释的类。同样,不符合 JPA 规范。

    我使用 Maven 作为构建工具。几年前,我写了一个小插件,它会在构建过程中生成persistence.xml。该插件将从构建类路径中扫描以找出所有带注释的类,并将它们列出在生成的 persistence.xml 中。这是最乏味的,但结果是符合 JPA 规范的。一个缺点(我相信这不适用于大多数人)是查找发生在构建时,而不是运行时。这意味着,如果您的应用程序仅在部署/运行时提供实体 JAR,而不在构建时提供,那么这种方法将不起作用。

【讨论】:

对于第 3 点,似乎有人做出了类似的公开可用的东西:github.com/ljnelson/jpa-maven-plugin 对于第2点,您需要禁用通常在LocalContainerEntityManagerFactoryBean中配置的persistenceUnit。也就是说,如果指定了 persistenceUnit,那么 Spring 将忽略 packageToScan 设置。 这里有一个更新的 jpa-maven-plugin 分支:github.com/iSnow/jpa-maven-plugin【参考方案4】:

我有类似的问题和solved it 与 Hibernate 的Integrator SPI:

@Override
public void integrate(Configuration configuration,
    SessionFactoryImplementor sessionFactory,
    SessionFactoryServiceRegistry serviceRegistry) 

    configuration.addAnnotatedClass(MyEntity.class);
    configuration.buildMappings();

集成器以Java service 的形式提供。

【讨论】:

【参考方案5】:

Ejb3Configuration 已在 4.3.0 中删除。如果不想创建 Hibernate 的 Integrator,可以使用属性hibernate.ejb.loaded.classes

properties.put(org.hibernate.jpa.AvailableSettings.LOADED_CLASSES, entities);
Persistence.createEntityManagerFactory("persistence-unit", properties);

其中entities 是实体类的List&lt;Class&gt;

【讨论】:

LOADED_CLASSES 设置被标记为“仅供内部使用”,并且未在使用 Maven 下载的 jar 中定义。 嘿,我目前正在使用它来让一个 persistence.xml 指向多个 jar 文件!知道为什么它被删除了吗?【参考方案6】:

我有一个稍微不同的设置,我将 persistence.xml 放在 WAR 文件中,但它的一些依赖项包括 @Entity 注释类,以包含在持久性单元中。

我使用 Maven 解决了我的问题,有点像 #3 中描述的 Adrian Shum,但使用该元素包含要扫描的 jar 以查找 @Entity 注释。

我在 my-web/pom.xml 中为每个依赖项添加了一个属性,包括额外的实体。我所有的 jar 都是 Maven 多项目构建的一部分,所以对我来说它看起来像。

<properties>
    <common.jar>common-$project.version.jar</common.jar>
    <foo.jar>foo-$project.version.jar</foo.jar>
</properties>

我随后将以下内容添加到 persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" ... >
    <persistence-unit name="primary">
        <jta-data-source>java:jboss/datasources/mysource</jta-data-source>

        <jar-file>lib/$common.jar</jar-file>
        <jar-file>lib/$foo.jar</jar-file>

        ...
    </persistence-unit>
</persistence>

最后,我在 web/pom.xml 中配置了 maven-resource-plugin,用 POM 中设置的属性替换了 persistence.xml 中的 $expressions

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
      <includes>
        <include>**/persistence.xml</include>
      </includes>
    </resource>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>false</filtering>
      <excludes>
        <exclude>**/persistence.xml</exclude>
      </excludes>
    </resource>
  </resources>
  ...
</build>

【讨论】:

【参考方案7】:

对于 JPA 2+,这可以解决问题

<jar-file></jar-file>

扫描战争中的所有罐子以查找带注释的@Entity 类

【讨论】:

【参考方案8】:

你可以使用这个概念: https://wiki.eclipse.org/Packaging_and_Deploying_EclipseLink_JPA_Applications_(ELUG)

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
   <persistence-unit name="mamcaPU" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>mamcaPU</jta-data-source>
        <mapping-file>/META-INF/common-layer-mappings.xml</mapping-file>
    </persistence-unit>
</persistence>

common-layer-mappings.xml

<entity-mappings>   
   <entity class="vub.be.mamca.entity.Surveyactorgrouptable"></entity>
   <entity class="vub.be.mamca.entity.Userevaluationelicitationtable"></entity>
   <entity class="vub.be.mamca.entity.Userevaluationtable"></entity>
   <entity class="vub.be.mamca.entity.Usertable"></entity>
   <entity class="vub.be.mamca.entity.Userweightelicitationtable"></entity>
</entity-mappings>

【讨论】:

以上是关于JPA 2.0:自动将实体类*从不同的 jar* 添加到 PersistenceUnit的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JPA 2.0 中自动检测实体

将实体从库引用到 JPA 中的另一个库

从 JPA 注释的实体类自动生成数据模式

JPA 持久类从不同的 JAR 扩展另一个类

JPA,如何使用同一个类(实体)来映射不同的表?

如何从 JPA 注释的实体类生成 JPA 映射文件?