JPA 2.0: автоматическое добавление классов сущностей в PersistenceUnit * из разных jar * - PullRequest
38 голосов
/ 17 июня 2011

У меня есть приложение Java SE на основе CDI, созданное Maven, которое имеет модуль 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.

  • Есть ли какое-то такое решение?
  • Есть ли способсоздать PU из persistence.xml и добавить к нему классы программно?
  • Можно ли добавить классы @Entity к EntityManagerFactory после его создания?

Обновление: Я нашел в org.​hibernate.​ejb.​Ejb3Configuration:

public Ejb3Configuration configure(String persistenceUnitName, Map integration)  

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

Ответы [ 8 ]

11 голосов
/ 07 декабря 2012

Существует несколько способов ее решения:

  1. Как описано в Нужны ли элементы в файле persistence.xml? , вы можете установить свойство hibernate.archive.autodetection, и Hibernate должен иметь возможность искать все аннотированные классы из classpath. Однако это не соответствует спецификации JPA.

  2. Если вы используете Spring, начиная с Spring 3.1.2 (или, возможно, даже немного раньше), в LocalContainerEntityManagerFactoryBean вы можете определить packageToScan, который попросит LocalContainerEntityManagerFactoryBean сканировать в classpath, чтобы найти все аннотированные классы. Опять же, не соответствует спецификации JPA.

  3. Я использовал Maven в качестве инструмента для сборки. За годы до этого я написал небольшой плагин, который будет генерировать файл persistence.xml в процессе сборки. Плагин будет сканировать из сборки classpath, чтобы найти все аннотированные классы, и перечислить их в сгенерированном файле persistence.xml. Это наиболее утомительно, но результат соответствует спецификации JPA. Один недостаток (который не относится к большинству людей, которым я верю) - поиск происходит во время сборки, а не во время выполнения. Это означает, что если у вас есть приложение, для которого файлы JAR сущностей предоставляются только во время развертывания / выполнения, но не во время сборки, этот подход не будет работать.

7 голосов
/ 09 января 2014

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<Class> классов сущностей.

6 голосов
/ 26 марта 2014

У меня немного другая установка, в которой я помещаю файл persistence.xml в файл WAR, но некоторые из его зависимостей включают аннотированный @Entity, включенный в модуль сохранения.

Я решил свою проблему с помощью Maven, немного похожего на Адриана Шума, описанного в # 3, но с помощью элемента, включающего банки, которые нужно сканировать для аннотаций @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>

Наконец, я настраиваю maven-resource-plugin в web / pom.xml для замены $ выражений в постоянстве..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 голосов
/ 10 октября 2012

Я столкнулся с той же проблемой, и, к сожалению, простого решения не существует, похоже, JPA не был предназначен для такого использования. Одно из решений состоит в том, чтобы иметь только один persistence.xml на проект верхнего уровня (приложение). Это похоже на конфигурацию log4j. Файл persistence.xml должен перечислить все классы (используя <class>) или, если это не приложение Java SE, jar-файлы (используя <jar-file>), которые используются приложением. Таким образом, вы можете поместить сущности из нескольких модулей (jar) в одну единицу сохранения. Недостаток очевиден: вы должны перечислить все в одном файле.

РЕДАКТИРОВАТЬ: Я (возможно) нашел другое решение, которое использует файлы сопоставления XML, проверить его здесь: Несколько банок, решение с одной единицей персистентности?

1 голос
/ 07 января 2017

Вы можете использовать эту концепцию: 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>
0 голосов
/ 18 сентября 2014

для JPA 2+ это делает трюк

<jar-file></jar-file>

сканирует все банки в войне на предмет аннотированных классов @Entity

0 голосов
/ 09 декабря 2013

У меня похожая проблема, и решил ее с помощью Hibernate's Integrator SPI:

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

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

Интегратор предоставляется как Java-сервис .

0 голосов
/ 19 октября 2012

Возможно дублирование, см. мой ТАК вопрос .

Мы столкнулись с той же проблемой, и наш единственный способ - собрать все сущности в один файл persistence.xml для окончательного (веб-) приложения.

В то же время мы определяем отдельные файлы persistence.xml в наших ресурсах для тестирования, чтобы мы могли запускать приемочные тесты для каждого модуля.

...