Нужны ли мне элементы настойчивости.xml?


у меня очень простое упорство.xml-файл:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

    <persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
        <class>pl.michalmech.eventractor.domain.User</class>
        <class>pl.michalmech.eventractor.domain.Address</class>
        <class>pl.michalmech.eventractor.domain.City</class>
        <class>pl.michalmech.eventractor.domain.Country</class>

        <properties>
            <property name="hibernate.hbm2ddl.auto" value="validate" />
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>

</persistence>

и это работает.

но когда я удалить <class> элементы приложение не видит сущностей (все классы аннотируются с @Entity).

есть ли автоматический механизм для сканирования @Entity классы?

10 100

10 ответов:

сохранение.xml имеет jar-file что вы можете использовать. От учебник Java EE 5:

<persistence>
    <persistence-unit name="OrderManagement">
        <description>This unit manages orders and customers.
            It does not rely on any vendor-specific features and can
            therefore be deployed to any persistence provider.
        </description>
        <jta-data-source>jdbc/MyOrderDB</jta-data-source>
        <jar-file>MyOrderApp.jar</jar-file>
        <class>com.widgets.Order</class>
        <class>com.widgets.Customer</class>
    </persistence-unit>
</persistence>

этот файл определяет единицу сохранения по имени OrderManagement, который использует a Наша осведомленный источник данных jdbc/MyOrderDB. Элемент jar-file и class элементы определяют управляемые классы сохраняемости: классы сущностей, встраиваемые классы и сопоставленные суперклассы. Элемент jar-file элемент определяет JAR-файлы, которые отображаются в упакованном блоке настойчивость, содержащие управляемые классы персистентности, в то время как class элемент явно называет управляемые классы сохраняемости.

в случае гибернации, посмотрите на Глава 2. Настройка и настройка для более подробной информации.

EDIT: на самом деле, если вы не возражаете быть не совместимым со спецификациями, Hibernate поддерживает автоматическое обнаружение даже в Java SE. Для этого добавьте hibernate.archive.autodetection свойства:

<persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
  <!-- This is required to be spec compliant, Hibernate however supports
       auto-detection even in JSE.
  <class>pl.michalmech.eventractor.domain.User</class>
  <class>pl.michalmech.eventractor.domain.Address</class>
  <class>pl.michalmech.eventractor.domain.City</class>
  <class>pl.michalmech.eventractor.domain.Country</class>
   -->

  <properties>
    <!-- Scan for annotated classes and Hibernate mapping XML files -->
    <property name="hibernate.archive.autodetection" value="class, hbm"/>

    <property name="hibernate.hbm2ddl.auto" value="validate" />
    <property name="hibernate.show_sql" value="true" />
  </properties>
</persistence-unit>

на Java SE environment, по спецификации вы должны указать все классы как вы сделали:

список всех именованных управляемых классов сохраняемости должен быть указан в средах Java SE для обеспечения переносимости

и

если не предполагается, что аннотированные классы персистентности, содержащиеся в корне единицы персистентности, будут включены в единицу персистентности, элемент exclude-unlisted-classes должны использовать. Элемент exclude-unlisted-classes не предназначен для использования в средах Java SE.

(JSR-000220 6.2.1.6)

на Java EE среды, вы не должны сделать это, как поставщик сканирует для аннотаций для вас.

неофициально, вы можете попробовать указать <exclude-unlisted-classes>false</exclude-unlisted-classes> в вашей настойчивости.XML. По умолчанию этот параметр равен false в ээ и trueв SE. Оба EclipseLink и Toplink поддерживает это, насколько я могу судить. Но вы не должны полагаться на то, что он работает в SE, согласно спецификации, как указано выше.

вы можете попробовать следующее (Может или не может работать в SE-среды):

<persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
     <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
            <property name="hibernate.hbm2ddl.auto" value="validate" />
            <property name="hibernate.show_sql" value="true" />
    </properties>
</persistence-unit>

Мне нужны элементы класса в упорстве.xml?

нет, не обязательно. Вот как вы это делаете в Eclipse (Kepler tested):

щелкните правой кнопкой мыши проект, выберите свойства выберите JPA, в управление классом персистентности ТИК откройте аннотированные классы автоматически.

enter image description here

для тех, кто работает JPA весной, начиная с версии 3.1 и далее, вы можете установить packagesToScan собственность под LocalContainerEntityManagerFactoryBean и избавиться от настойчивости.xml вообще.

вот это Лоу-Даун

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

 <jar-file></jar-file>

сканировать все банки в войне для аннотированных @ Entity classes

Hibernate не поддерживает <exclude-unlisted-classes>false</exclude-unlisted-classes> под SE, (другой плакат упомянул, что это работает с TopLink и EclipseLink).

есть инструменты, которые будут автоматически генерировать список классов для сохранения.xml, например, мастер импорта схемы базы данных в IntelliJ. Как только вы получите начальные классы вашего проекта в persistence.xml это должно быть просто добавить / удалить отдельные классы вручную, как ваш проект прогрессирует.

Вы можете предоставить для jar-file путь элемента к папке с скомпилированными классами. Например, я добавил что-то подобное, когда готовил настойчивость.XML для некоторых интеграционных тестов:

 <jar-file>file:../target/classes</jar-file>

не уверен, что вы делаете что-то подобное тому, что я делаю, но Im генерирует загрузку исходного java из XSD с использованием JAXB в отдельном компоненте с использованием Maven. Допустим, этот артефакт называется "базовая модель"

Я хотел импортировать этот артефакт, содержащий источник java, и запустить hibernate по всем классам в моей "базовой модели" artifact jar и не указывать каждый явно. Я добавляю "базовую модель" в качестве зависимости для моего компонента hibernate, но проблема заключается в теге стойкость.xml позволяет указывать только абсолютные пути.

способ, которым я обошел его, заключается в том, чтобы скопировать мою зависимость от jar "базовой модели" явно в мой целевой dir, а также удалить его версию. Поэтому, если я создаю свой артефакт "базовая модель", он генерирует "базовую модель-1.0-снимок".jar", шаг copy-resources копирует его как " базовая модель.сосуд."

Итак, в вашем pom для компонента hibernate:

            <!-- We want to copy across all our artifacts containing java code
        generated from our scheams. We copy them across and strip the version
        so that our persistence.xml can reference them directly in the tag
        <jar-file>target/dependency/${artifactId}.jar</jar-file> -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.5.1</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>       
            <configuration>
                <includeArtifactIds>base-model</includeArtifactIds>
                <stripVersion>true</stripVersion>
            </configuration>        
        </plugin>

затем я вызываю плагин hibernate на следующем этапе "процесс-классы":

            <!-- Generate the schema DDL -->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>hibernate3-maven-plugin</artifactId>
            <version>2.2</version>

            <executions>
                <execution>
                    <id>generate-ddl</id>
                    <phase>process-classes</phase>
                    <goals>
                        <goal>hbm2ddl</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <components>
                    <component>
                        <name>hbm2java</name>
                        <implementation>annotationconfiguration</implementation>
                        <outputDirectory>/src/main/java</outputDirectory>
                    </component>
                </components>
                <componentProperties>
                    <persistenceunit>mysql</persistenceunit>
                    <implementation>jpaconfiguration</implementation>
                    <create>true</create>
                    <export>false</export>
                    <drop>true</drop>
                    <outputfilename>mysql-schema.sql</outputfilename>
                </componentProperties>
            </configuration>
        </plugin>

и, наконец, в моей настойчивости.xml я могу явно установить местоположение jar таким образом:

<jar-file>target/dependency/base-model.jar</jar-file>

и добавить свойство:

<property name="hibernate.archive.autodetection" value="class, hbm"/>

это не решение, а подсказка для тех, кто использует Spring:

Я пытался использовать org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean с persistenceXmlLocation но с этим я должен был предоставить <class> элементы (даже если persistenceXmlLocation просто указал на META-INF/persistence.xml).

, когда не используя persistenceXmlLocation Я мог бы пропустить эти <class> элементы.

я не уверен, что это решение находится под спецификацией, но я думаю, что могу поделиться для других.

дерево зависимостей

мой-сущностей.банку

содержит только классы сущностей. Нет META-INF/persistence.xml.

мои услуги.банку

зависит от my-entities. Содержит только компоненты EJB.

мой-ресурсов.банку

зависит от my-services. Содержит классы ресурсов и META-INF/persistence.xml.

проблемы

  • как можем ли мы указать <jar-file/> элемент my-resources как вариант-постфикс название артефакта временная зависимость?
  • как мы можем синхронизировать <jar-file/> значение элемента и фактическая переходная зависимость?

решение

прямая (избыточный?) зависимость и фильтрация ресурсов

я помещаю свойство и зависимость в my-resources/pom.xml.

<properties>
  <my-entities.version>x.y.z-SNAPSHOT</my-entities.version>
</properties>
<dependencies>
  <dependency>
    <!-- this is actually a transitive dependency -->
    <groupId>...</groupId>
    <artifactId>my-entities</artifactId>
    <version>${my-entities.version}</version>
    <scope>compile</scope> <!-- other values won't work -->
  </dependency>
  <dependency>
    <groupId>...</groupId>
    <artifactId>my-services</artifactId>
    <version>some.very.sepecific</version>
    <scope>compile</scope>
  </dependency>
<dependencies>

а теперь persistence.xml готов к фильтруется

<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
  <persistence-unit name="myPU" transaction-type="JTA">
    ...
    <jar-file>lib/my-entities-${my-entities.version}.jar</jar-file>
    ...
  </persistence-unit>
</persistence>

Плагин Maven Enforcer

С dependencyConvergence правило, мы можем заверить, что my-entities' версия одинакова как в прямом, так и в транзитивном режиме.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>1.4.1</version>
  <executions>
    <execution>
      <id>enforce</id>
      <configuration>
        <rules>
           <dependencyConvergence/>
        </rules>
      </configuration>
      <goals>
        <goal>enforce</goal>
      </goals>
    </execution>
  </executions>
</plugin>