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 规范。
我使用 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<Class>
。
【讨论】:
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的主要内容,如果未能解决你的问题,请参考以下文章