我有一个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)
答案 0 :(得分:11)
有几种方法可以解决它:
如Do I need <class> elements in persistence.xml?中所述,您可以设置hibernate.archive.autodetection
属性,Hibernate应该能够从classpath中查找所有带注释的类。但是,这不符合JPA规范。
如果您使用的是Spring,从Spring 3.1.2开始(或者可能更早一点),在LocalContainerEntityManagerFactoryBean
中,您可以定义packageToScan
,LocalContainerEntityManagerFactoryBean
将{{1}}在类路径中扫描以查找所有带注释的类。同样,不符合JPA规范。
我使用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);
其中entities
是List<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类
的罐子