JPA 2.0: автоматическое добавление классов сущностей в PersistenceUnit * из разных jar*
У меня есть приложение Java SE на основе CDI, созданное Maven, в котором есть основной модуль и другие модули.
Ядро имеет persistence.xml
и некоторые лица. Модули имеют дополнительные объекты.
Как я могу добавить сущности в центр внимания персистентности?
Я прочитал руководство по Hibernate, http://docs.jboss.org/hibernate/stable/entitymanager/reference/en/html/configuration.html
Я также видел эти вопросы ТАК
- Как я могу объединить / расширить единицы персистентности из разных JAR-файлов?
- определить классы сущностей jpa вне файла persistence.xml
- Программно загружать классы сущностей с помощью JPA 2.0?
Я ищу решение, в котором Hibernate сканирует все загруженные классы или выбирает какой-либо файл конфигурации из других jar-файлов (как, например, CDI делает с beans.xml
).
Мое приложение не использует Spring. Я не настаиваю на переносимости - я буду придерживаться Hibernate.
- Есть ли такое решение?
- Есть ли способ создать ПУ из
persistence.xml
и добавить классы к нему программно? - Могу ли я добавить классы @Entity в
EntityManagerFactory
после того как он был создан?
Обновление: я нашел в org.hibernate.ejb.Ejb3Configuration
:
public Ejb3Configuration configure(String persistenceUnitName, Map integration)
8 ответов
Есть несколько способов решить это:
Как описано в " Нужны ли мне элементы
в файле persistence.xml?" Вы можете установитьhibernate.archive.autodetection
свойство и Hibernate должны иметь возможность искать все аннотированные классы из classpath. Однако это не соответствует спецификации JPA.Если вы используете Spring, начиная с Spring 3.1.2 (или, возможно, даже немного раньше), в
LocalContainerEntityManagerFactoryBean
Вы можете определитьpackageToScan
который спроситLocalContainerEntityManagerFactoryBean
сканировать в classpath, чтобы найти все аннотированные классы. Опять же, не соответствует спецификации JPA.Я использовал Maven в качестве инструментов для сборки. За годы до этого я написал небольшой плагин, который будет генерировать файл persistence.xml в процессе сборки. Плагин будет сканировать из сборки classpath, чтобы найти все аннотированные классы, и перечислить их в сгенерированном файле persistence.xml. Это наиболее утомительно, но результат соответствует спецификации JPA. Один недостаток (который не относится к большинству людей, которым я верю) - поиск происходит во время сборки, а не во время выполнения. Это означает, что если у вас есть приложение, для которого JAR-объекты сущностей предоставляются только во время развертывания / выполнения, но не во время сборки, этот подход не сработает.
Ejb3Configuration была удалена в 4.3.0. Если вы не хотите создавать интегратор 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, как Адриан Шум, описанный в #3, но используя элемент для включения 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>
Наконец, я настраиваю maven-resource-plugin в web / pom.xml для замены $ выражений в 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>
Я столкнулся с той же проблемой, и, к сожалению, простого решения не существует, похоже, JPA не был разработан для такого использования. Одним из решений является наличие только одного файла persistence.xml на проект (приложение) верхнего уровня. Это похоже на конфигурацию log4j. Файл persistence.xml должен перечислить все классы (используя <class>
) или, если это не приложение Java SE, jar-файлы (используя <jar-file>
), которые используются приложением. Таким образом, вы можете поместить объекты из нескольких модулей (jar-файлов) в один постоянный модуль. Недостаток очевиден: вы должны перечислить все в одном файле.
РЕДАКТИРОВАТЬ: Я (возможно) нашел другое решение, которое использует файлы сопоставления XML, проверьте его здесь: несколько JAR-решений, решение для одной единицы сохраняемости?
Вы можете использовать эту концепцию: 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>
Возможный дубликат, смотрите мой ТАК вопрос.
Мы столкнулись с той же проблемой, и единственный найденный способ - это собрать все сущности в один файл persistence.xml для окончательного (веб-) приложения.
В то же время мы определяем отдельные файлы persistence.xml в наших тестовых ресурсах, чтобы мы могли запускать приемочные тесты для каждого модуля.
У меня есть похожая проблема, и я решил ее с помощью Hibernate's Integrator
SPI:
@Override
public void integrate(Configuration configuration,
SessionFactoryImplementor sessionFactory,
SessionFactoryServiceRegistry serviceRegistry) {
configuration.addAnnotatedClass(MyEntity.class);
configuration.buildMappings();
}
Интегратор предоставляется как сервис Java.
Для JPA 2+ это делает свое дело
<jar-file></jar-file>
сканировать все банки в войне для аннотированных классов @Entity