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

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

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

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

我也看到了这些问题

  • 如何合并/扩展来自不同JAR的持久化单元?
  • 在persistence.xml之外定义jpa实体类
  • 使用JPA 2.0编程加载实体类?

我正在寻找一个解决scheme,Hibernate可以扫描所有加载的类,或者从其他jar文件中获取一些configuration文件(比如CDI用beans.xml )。

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

  • 有没有这样的解决scheme?
  • 有没有办法从persistence.xml创build一个PU,并以编程方式添加类?
  • EntityManagerFactory创build后可以添加@ Entity类吗?

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

 public Ejb3Configuration configure(String persistenceUnitName, Map integration) 

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

有几种方法来解决它:

  1. 正如我在persistence.xml中需要<class>元素所描述的那样? ,你可以设置hibernate.archive.autodetection属性,Hibernate应该能够从classpath中查找所有带注释的类。 但是,这不符合JPA规范。

  2. 如果从Spring 3.1.2(或者甚至更早)使用Spring,可以在LocalContainerEntityManagerFactoryBean中定义packageToScan ,它将要求LocalContainerEntityManagerFactoryBean在classpath中扫描以查找所有带注释的类。 同样,不符合JPA规范。

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

Ejb3Configuration已在4.3.0中删除。 如果你不想创build一个Hibernate的集成器,你可以使用属性“hibernate.ejb.loaded.classes”。

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

其中persistentClasses包含具有实体类的Class []。

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

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

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

 <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中configurationmaven-resource-plugin,将persistence.xml中的$expression式replace为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> 

我遇到了同样的问题,不幸的是没有简单的解决scheme,它基本上看起来像JPA不是这样devise的。 其中一个解决scheme是每个顶级项目(应用程序)只有一个 persistence.xml。 这有点类似于log4jconfiguration。 persistence.xml必须列出所有类(使用<class> ),或者如果不是Java SE应用程序,则列出应用程序使用的jar文件(使用<jar-file> )。 这样你就可以把来自多个模块(jar子)的实体放到单个持久化单元中。 缺点是显而易见的:你必须在一个文件中列出所有的东西。

编辑:我(可能)发现了另一个使用XML映射文件的解决scheme,请看这里: 多个jar子,单个持久性单元解决scheme?

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

可能的重复,看我的SO问题 。

我们面临同样的问题,我们发现的唯一方法是将所有实体都集中在一个persistence.xml中,以用于最终的(web)应用程序。

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

我有一个类似的问题, 并用Hibernate的Integrator SPI 解决 :

 @Override public void integrate(Configuration configuration, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { configuration.addAnnotatedClass(MyEntity.class); configuration.buildMappings(); } 

Integrator作为Java服务提供 。

对于JPA 2+,这个技巧

 <jar-file></jar-file> 

扫描战争中的所有jar子,注释@Entity类