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

发布于 2024-11-16 03:15:59 字数 1656 浏览 3 评论 0原文

我有一个 Maven 构建的基于 CDI 的 Java SE 应用程序,它有一个 core 模块和其他模块。
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.冬眠。 ejb。 Ejb3Configuration

public Ejb3Configuration configure(String persistenceUnitName, Map integration)  

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

I have a maven-built CDI-based Java SE app, which has a core module, and other modules.
Core has the persistence.xml and some entities.
Modules have additional entities.

How can I add the entities to the spotlight of the persistence unit?

I have read Hibernate manual, http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html#setup-configuration-packaging

I have also seen these SO questions

I am looking for a solution where Hibernate would scan for all loaded classes, or, would pick up some config file form the other jars (like e.g. CDI does with beans.xml).

My app does not use Spring.
I don't insist on portability - I'll stick with Hibernate.

  • Is there some such solution?
  • Is there's a way to create a PU from persistence.xml and add classes to it programmatically?
  • Can I add @Entity classes to EntityManagerFactory after it was created?

Update: I found in org.​hibernate.​ejb.​Ejb3Configuration:

public Ejb3Configuration configure(String persistenceUnitName, Map integration)  

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

橘香 2024-11-23 03:15:59

有几种方法可以解决它:

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

  2. 如果您使用 Spring,从 Spring 3.1.2(或者可能更早)开始,在 LocalContainerEntityManagerFactoryBean 中,您可以定义 packageToScan ,它会询问 LocalContainerEntityManagerFactoryBean 在类路径中扫描以查找所有带注释的类。同样,不符合 JPA 规范。

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

There are several way to solve it:

  1. As described in Do I need <class> elements in persistence.xml?, you can set hibernate.archive.autodetection property and Hibernate should be able to look up all annotated classes from classpath. However, that's not JPA spec compliant.

  2. If you are using Spring, from Spring 3.1.2 (or probably even a bit earlier), in LocalContainerEntityManagerFactoryBean, you can define packageToScan which will ask LocalContainerEntityManagerFactoryBean to scan in classpath to find all annotated classes. Again, not JPA spec compliant.

  3. I was using Maven as build tools. Years before, I have written a little plugin which will generate persistence.xml during build process. The plugin will scan from build classpath to find out all annotated classes, and list them in the generated persistence.xml. This is most tedious but the result is JPA spec compliant. One drawback (which does not apply to most people I believe) is the lookup happens in build-time, not runtime. That means if you are having an application for which entities JARs are provided only at deploy/runtime but not build time, this approach is not going to work.

浮光之海 2024-11-23 03:15:59

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

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

其中entities是实体类的List

Ejb3Configuration has been removed in 4.3.0. If you don't want to create a Hibernate's Integrator, you can use the property hibernate.ejb.loaded.classes.

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

Where entities is a List<Class> of entity classes.

怀念你的温柔 2024-11-23 03:15:59

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

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

我为每个依赖项(包括额外的实体)添加了一个属性到 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,以将 persistence.xml 中的 $expressions 替换为 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>

I have a slightly different setup where I am placing persistence.xml in the WAR file but some of its dependencies includes @Entity annotated classed to include in the persistence unit.

I have solved my problem using Maven a bit like Adrian Shum described in #3, but using the element to include the jars to be scanned for @Entity annotations.

I added a property to my-web/pom.xml for each dependency including extra entities. All my jars are part of a Maven multiproject build so for me it looks like.

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

I thereafter add the following to the 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>

Lastly I configure the maven-resource-plugin in web/pom.xml to replace the $expressions in persistence.xml with the properties set in the 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>
懒猫 2024-11-23 03:15:59

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

编辑:我(可能)找到了另一个使用 XML 映射文件的解决方案,请在此处查看:多个罐子、单个持久单元解决方案?

I've experienced the same issue and unfortunately there is no easy solution, it basically looks like JPA wasn't designed to be used this way. One of solutions is to have just one persistence.xml per top-level project (application). It's kind of similar to log4j configuration. The persistence.xml has to list all classes (using <class>) or, if it's not Java SE app, jar files (using <jar-file>) that are used by the application. This way you can put entities from multiple modules (jars) into single persistence unit. The drawback is obvious: you have to list everything in one file.

EDIT: I have (possibly) found another solution that uses XML mapping files, check it out here: Multiple jars, single persistence unit solution?

山人契 2024-11-23 03:15:59

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

公共层映射.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>

You can do use this concept:
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>
指尖凝香 2024-11-23 03:15:59

可能重复,请参阅我的SO问题

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

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

Possible duplicate, see my SO question.

We faced the same problem and the only way we found was to accumulate all entities in one persistence.xml for the final (web-)application.

At the same time we define separate persistence.xml files in our test resources so we can run acceptance tests per module.

清风挽心 2024-11-23 03:15:59

我有类似的问题,已解决它与Hibernate的Integrator SPI:

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

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

Integrator 以 Java 服务

I have a similar problem and solved it with Hibernate's Integrator SPI:

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

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

The Integrator is provided as Java service.

千柳 2024-11-23 03:15:59

对于 JPA 2+,这可以扫描

<jar-file></jar-file>

war 中所有 jar 来查找带注释的 @Entity 类

for JPA 2+ this does the trick

<jar-file></jar-file>

scan all jars in war for annotated @Entity classes

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文