persistence.xml에 <class> 요소가 필요합니까?


110

매우 간단한 persistance.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클래스 를 스캔하는 자동 메커니즘이 있습니까?

답변:


78

persistence.xml에는 jar-file사용할 수있는가 있습니다. 에서 자바 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>

이 파일은 OrderManagementJTA 인식 데이터 소스를 사용하는 라는 지속성 단위를 정의합니다 jdbc/MyOrderDB. jar-fileclass엔티티 클래스 임베드 클래스 및 매핑 수퍼 : 요소 영속성 관리 클래스를 지정한다. jar-file그동안 클래스 영속성 관리 포함하는 패키지 퍼시스턴스 유닛에게 표시 소자 지정 JAR 파일 class소자 명시 클래스 이름은 영속성 관리.

Hibernate의 경우 Chapter2를 살펴보십시오 . 자세한 내용은 설정 및 구성 도 참조하십시오.

편집 : 실제로 사양을 준수하지 않아도 괜찮다면 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>

13
알지만 엔티티 (@Entity)는 별도의 Maven 프로젝트에 있으므로 jar 파일 이름은 모든 빌드에서 변경 될 수 있습니다. 특정 패키지 또는 클래스 경로에서 모두 스캔 할 것을 찾고 있습니다. 나는 persistence.xml 파일에 많은 <class> 요소를 입력하는 것이 게으르다.
Michał Mech

모든 빌드에서?! 이유는 묻지 않겠지 만 ...이 문제를 해결하기 위해 필터링을 사용할 수 있습니다.
Pascal Thivent

모든 사람이 정확히는 아니지만 변화에 저항하고 싶습니다.
Michał Mech 09.11.23

5
고대 스레드는 알고 있지만 jpa-maven-plugin을 살펴보십시오 .
Laird Nelson

persistence.xml에서 <mapping-file> 요소 (엔티티 목록 포함)를 사용할 수 있으므로 사용 된 파일의 동일한 이름을 유지하고 참조 된 jar의 빌드에 통합 할 수 있습니다.
med_alpa

44

에서 자바 SE 환경, 사양에 의해 모든 클래스를 지정해야 당신이했던 것처럼 :

이식성을 보장하려면 모든 명명 된 관리 지속성 클래스 목록을 Java SE 환경에 지정해야합니다.

지속성 단위의 루트에 포함 된 어노테이션이있는 지속성 클래스가 지속성 단위에 포함되도록 의도되지 않은 경우 exclude-unlisted-classes 요소를 사용해야합니다. exclude-unlisted-classes 요소는 Java SE 환경에서 사용하기위한 것이 아닙니다.

(JSR-000220 6.2.1.6)

에서 자바 EE 환경, 당신은하지 않습니다 당신을위한 주석 공급자 스캔으로이 작업을 수행 할 수 있습니다.

비공식적으로 <exclude-unlisted-classes>false</exclude-unlisted-classes>persistence.xml에서 설정 을 시도 할 수 있습니다 . 이 매개 변수의 기본값 false은 EE 및 trueSE입니다. EclipseLinkToplink 모두 내가 말할 수있는 한 이것을 지원합니다. 그러나 위에서 언급했듯이 사양에 따라 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>

2
<exclude-unlisted-classes>false</exclude-unlisted-classes>제이보스 8.2.1.Final + 최대 절전 모드 4.3.7 작동하지 않았다
안드레아스 디트리히

12

persistence.xml에 Class 요소가 필요합니까?

아니요, 반드시 그런 것은 아닙니다. 다음은 Eclipse에서 수행하는 방법입니다 (Kepler 테스트 됨).

프로젝트를 마우스 오른쪽 버튼으로 클릭하고 속성을 클릭 한 다음 JPA를 선택 하고 지속성 클래스 관리 틱에서 자동으로 어노테이션이있는 클래스 발견을 선택하십시오 .

여기에 이미지 설명 입력


9
왜 찬성? OP는 Eclipse를 언급하지도 않으며이 답변은이 Eclipse 기능이 IDE없이 수행 할 수 있도록 내부에서 수행하는 작업을 보여주지 않습니다.
Artem Novikov

2
@Artem Novikov : 질문이 다른 환경에서 자주 발생하기 때문에이 문제가 가혹하다는 것을 알게되었습니다. 여기서 유용한 힌트를 제공하거나 돕고 싶습니다! (나를 위해) Eclipse는 이와 같은 개발을위한 공통 IDE이기 때문에 유용하고 내부적으로는 그다지 중요하지 않지만 모든 관련 작업 공간 프로젝트를 포함 할 것이라고 생각합니다 (예 : 내 프로젝트는 의존적 임).
안드레아스 디트리히

stackoverflow.com/questions/17951297/… 좋은 속임수이지만 엔티티가 persistence.xml과 동일한 클래스 로더에있는 경우에만 작동합니다
Pierluigi Vernetto

@abbas persistence.xmlEclipse가 생성 하는 것을 보여주세요 .
Frans

12

Spring에서 JPA를 실행하는 경우 3.1 버전부터 packagesToScan속성을 설정 LocalContainerEntityManagerFactoryBean하고 persistence.xml을 모두 제거 할 수 있습니다 .

여기에 낮은 다운


나를 위해 일했습니다! 시나리오는 봄 4 + 최대 절전 모드 + jpa2 + maven이었습니다. JUnit 테스트는 내 엔티티를 찾지 못했지만이 설정으로 작업을 수행했습니다.
SatA 2014

8

jar-file컴파일 된 클래스가있는 폴더에 대한 요소 경로를 제공 할 수 있습니다 . 예를 들어 몇 가지 통합 테스트에 persistence.xml을 준비 할 때 다음과 같은 내용을 추가했습니다.

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

이것이 제가 찾던 것입니다!
xtian aug

EclipseLink에서도 작동합니다!
Bombe 2019 년

8

JPA 2+의 경우 이것은 트릭을 수행합니다.

 <jar-file></jar-file>

주석이 달린 @Entity 클래스에 대해 전쟁의 모든 항아리를 스캔하십시오.


2
이것에 대한 더 많은 정보가 있습니까? 이것은 우연히 작동합니까 아니면 사양에 기록되어 있습니까? 구현에 의존합니까?
markus

스캐너가 AbstractScannerImpl를 확장 클래스에 최대 절전 모드 - 아니 생각을 경우의 버그의보고와 기능, 죄송합니다
eriskooo

1
Hibernate 5.1.2.Final이있는 Java SE에서는이 솔루션이 작동하지 않습니다. Hibernate는 jar 파일 이름 ( java.lang.IllegalArgumentException: Unable to visit JAR file:)을 예상합니다 .
Stephan

1
공장! : 제이보스 8.2.1.Final + 최대 절전 모드 4.3.7.Final와
안드레아스 디트리히

Thx man, 많이 검색했으며 이것은 사용 가능한 가장 좋은 솔루션입니다. Wildfly10 + Hibernate 5.0.7 작동.
boutta

7

Hibernate는 <exclude-unlisted-classes>false</exclude-unlisted-classes>SE에서 지원하지 않습니다 (다른 포스터가 TopLink 및 EclipseLink에서 작동한다고 언급했습니다).

IntelliJ의 Import Database Schema 마법사와 같이 persistence.xml에 클래스 목록을 자동 생성하는 도구가 있습니다. persistence.xml에 프로젝트의 초기 클래스가 있으면 프로젝트가 진행됨에 따라 단일 클래스를 직접 추가 / 제거하는 것이 간단해야합니다.


Java SE의 엔티티 자동 감지는 JPA의 일부가 아닙니다. 이에 의존하는 응용 프로그램은 이식 할 수 없습니다.
Pascal Thivent

4

내가하고있는 것과 비슷한 일을하고 있는지 확실하지 않지만 Maven을 사용하여 별도의 구성 요소에서 JAXB를 사용하여 XSD에서 소스 Java로드를 생성합니다. 이 아티팩트를 "기본 모델"이라고 가정 해 보겠습니다.

Java 소스가 포함 된이 아티팩트를 가져 와서 "기본 모델"아티팩트 jar의 모든 클래스에 대해 최대 절전 모드를 실행하고 각각을 명시 적으로 지정하지 않으려 고했습니다. 내 최대 절전 모드 구성 요소에 대한 종속성으로 "base-model"을 추가했지만 문제는 persistence.xml의 태그가 절대 경로를 지정할 수만 있다는 것입니다.

내가 얻은 방법은 내 "기본 모델"jar 종속성을 내 대상 디렉토리에 명시 적으로 복사하고 버전을 제거하는 것입니다. 따라서 "base-model"아티팩트를 빌드하면 "base-model-1.0-SNAPSHOT.jar"이 생성되지만 복사 리소스 단계에서는 "base-model.jar"로 복사합니다.

따라서 최대 절전 구성 요소에 대한 pom에서 :

            <!-- 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>

그런 다음 다음 단계에서 "process-classes"에서 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>

마지막으로 persistence.xml에서 jar의 위치를 ​​명시 적으로 설정할 수 있습니다.

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

속성을 추가합니다.

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

3

그것은 해결책이 아니라 Spring을 사용하는 사람들을위한 힌트입니다.

나는 org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean설정과 함께 사용하려고 persistenceXmlLocation했지만 이것으로 <class>요소 를 제공 해야했습니다 ( persistenceXmlLocation방금을 가리 키 더라도 META-INF/persistence.xml).

사용 하지 않을 때는 persistenceXmlLocation이러한 <class>요소를 생략 할 수 있습니다.


persistenceXmlLocationLocalContainerEntityManagerFactoryBean설정 에서 속성을 사용 했습니다 . 그러나 <class>요소를 생략해도 모든 쿼리가 작동 합니다. Spring / Hibernate / Maven 애플리케이션에 있습니다. 그러나 당신은 "persistenceXmlLocation을 사용하지 않을 때 이러한 <class> 요소를 생략 할 수 있습니다." 라고 힌트를 합니다. 그러나 그것은 나를위한 다른 방법입니다.
Lucky

@Ethan 당신이 옳습니다. 왜냐하면 persistenceXmlLocation은 소스를 살펴보면 packagesToScan을 재정의하기 때문입니다. 따라서 packagesToScan을 사용할 때 사용하지 마십시오.
Artem Novikov

2

이 솔루션이 사양에 해당하는지 확실하지 않지만 다른 사람들과 공유 할 수 있다고 생각합니다.

종속성 트리

my-entities.jar

엔티티 클래스 만 포함합니다. 아니 META-INF/persistence.xml.

my-services.jar

에 따라 다릅니다 my-entities. EJB 만 포함합니다.

my-resources.jar

에 따라 다릅니다 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>

0

모든 경우에 반드시 그런 것은 아닙니다.

Jboss 7.0.8 및 Eclipselink 2.7.0을 사용하고 있습니다. 제 경우에는 persistence.xml에 동일한 항목을 추가하지 않고 엔티티를로드하기 위해 Jboss Standalone XML에 다음 시스템 속성을 추가했습니다.

<property name="eclipselink.archive.factory" value="org.jipijapa.eclipselink.JBossArchiveFactoryImpl"/>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.