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

时间:2011-06-17 02:16:36

标签: hibernate configuration entity jpa-2.0 entities

我有一个maven构建的基于CDI的Java SE应用程序,它有一个核心模块和其他模块。
Core有persistence.xml和一些实体。 模块有其他实体。

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

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

我也看过这些SO问题

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

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

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

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

public Ejb3Configuration configure(String persistenceUnitName, Map integration)  

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

8 个答案:

答案 0 :(得分:11)

有几种方法可以解决它:

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

  2. 如果您使用的是Spring,从Spring 3.1.2开始(或者可能更早一点),在LocalContainerEntityManagerFactoryBean中,您可以定义packageToScanLocalContainerEntityManagerFactoryBean将{{1}}在类路径中扫描以查找所有带注释的类。同样,不符合JPA规范。

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

答案 1 :(得分:7)

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

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

其中entitiesList<Class>个实体类。

答案 2 :(得分:6)

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

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

我为my-web / pom.xml添加了一个属性,用于包含额外实体的每个依赖项。我所有的罐子都是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,将persistence.xml中的$表达式替换为POM中设置的属性

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

答案 3 :(得分:3)

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

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

答案 4 :(得分:1)

你可以使用这个概念: 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>

共层-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>

答案 5 :(得分:0)

可能重复,请参阅my SO question

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

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

答案 6 :(得分:0)

我遇到了类似的问题,并且solved it使用了Hibernate的Integrator SPI:

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

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

Integrator以Java service提供。

答案 7 :(得分:-4)

对于JPA 2+,这就是诀窍

<jar-file></jar-file>

在战争中扫描所有带注释的@Entity类

的罐子