ฉันต้องการองค์ประกอบ <class> ใน persistence.xml หรือไม่?


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ที่คุณสามารถใช้ได้ จากบทช่วยสอน 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 JTA ทราบ และองค์ประกอบระบุการจัดการเรียนการติดตา: เรียนนิติบุคคลเรียนฝังและ superclasses แมป องค์ประกอบระบุไฟล์ JAR ที่สามารถมองเห็นไปยังหน่วยติดตาแพคเกจที่มีการจัดการเรียนการติดตาในขณะที่องค์ประกอบชื่ออย่างชัดเจนมีการจัดการเรียนการติดตาjdbc/MyOrderDBjar-fileclassjar-fileclass

ในกรณีของ 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 จึงสามารถเปลี่ยนได้ในทุกบิลด์ ฉันกำลังมองหาสิ่งที่จะสแกนทั้งหมดในแพ็คเกจหรือ classpath เฉพาะ ฉันแค่ขี้เกียจพิมพ์องค์ประกอบ <class> จำนวนมากในไฟล์ persistence.xml
Michał Mech

ในการสร้างทุกครั้ง! ฉันจะไม่ถามว่าทำไม แต่ ... คุณสามารถใช้การกรองเพื่อแก้ปัญหานี้ได้
Pascal Thivent

ไม่ใช่ทุกคน แต่ฉันต้องการที่จะทนต่อการเปลี่ยนแปลง
Michał Mech

5
ด้ายโบราณฉันรู้ แต่มีลักษณะที่เป็นJPA-Maven ปลั๊กอิน
Laird Nelson

คุณสามารถใช้อิลิเมนต์ <mapping-file> (ซึ่งมีรายการเอนทิตี) ใน persistence.xml ดังนั้นคุณจึงสามารถใช้ชื่อไฟล์ที่ใช้เหมือนเดิมและรวมเข้ากับบิวด์ของขวดที่อ้างอิง
med_alpa

44

ในสภาพแวดล้อม Java SE ตามข้อกำหนดคุณต้องระบุคลาสทั้งหมดตามที่คุณได้ทำ:

รายการคลาสการคงอยู่ที่มีการจัดการที่มีชื่อทั้งหมดต้องระบุไว้ในสภาพแวดล้อม Java SE เพื่อประกันความสามารถในการพกพา

และ

หากไม่ได้ตั้งใจให้คลาสการคงอยู่ที่มีคำอธิบายประกอบที่มีอยู่ในรูทของหน่วยการคงอยู่รวมอยู่ในหน่วยการคงอยู่ควรใช้อิลิเมนต์คลาสที่ไม่รวมที่ไม่แสดง อิลิเมนต์คลาสที่ไม่รวมไม่อยู่ในรายการไม่ได้มีไว้สำหรับใช้ในสภาพแวดล้อม Java SE

(JSR-000220 6.2.1.6)

ในสภาพแวดล้อม Java EE คุณไม่จำเป็นต้องทำเช่นนี้เนื่องจากผู้ให้บริการสแกนหาคำอธิบายประกอบให้คุณ

อย่างไม่เป็นทางการคุณสามารถลองตั้งค่า<exclude-unlisted-classes>false</exclude-unlisted-classes>ใน persistence.xml ของคุณ พารามิเตอร์นี้มีค่าเริ่มต้นเป็นfalseEE และtrueSE ทั้ง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>

2
<exclude-unlisted-classes>false</exclude-unlisted-classes>ไม่สามารถใช้งานกับ WildFly 8.2.1 Final + Hibernate 4.3.7
Andreas Dietrich

12

ฉันต้องการองค์ประกอบของคลาสใน persistence.xml หรือไม่

ไม่คุณไม่จำเป็น นี่คือวิธีที่คุณทำใน Eclipse (ทดสอบโดย Kepler):

คลิกขวาที่โครงการคลิกPropertiesเลือกJPAในการจัดการระดับความคงทนเห็บค้นพบข้อเขียนเรียนโดยอัตโนมัติ

ใส่คำอธิบายภาพที่นี่


9
ทำไมต้องโหวต? OP ไม่ได้กล่าวถึง Eclipse ด้วยซ้ำและคำตอบนี้ไม่ได้แสดงว่าคุณลักษณะ Eclipse นี้ทำอะไรภายใต้ประทุนเพื่อให้สามารถทำสิ่งนั้นได้โดยไม่ต้องใช้ IDE
Artem Novikov

2
@Artem Novikov: ฉันพบว่าสิ่งนี้รุนแรงเนื่องจากบ่อยครั้งที่คำถามเกิดขึ้นจากสภาพแวดล้อมที่แตกต่างกันและที่นี่เราต้องการช่วยเหลือหรือให้คำแนะนำที่เป็นประโยชน์! (เช่นสำหรับฉัน) มันมีประโยชน์เนื่องจาก Eclipse เป็น IDE ทั่วไปสำหรับการพัฒนาแบบนี้และภายใต้ประทุนนั้นไม่สำคัญนัก แต่ฉันเดาว่ามันจะรวมโครงการพื้นที่ทำงานที่เกี่ยวข้องทั้งหมด (เช่นโครงการของฉันขึ้นอยู่กับ)
Andreas Dietrich

stackoverflow.com/questions/17951297/…เคล็ดลับที่ดี แต่เห็นได้ชัดว่ามันใช้งานได้ก็ต่อเมื่อเอนทิตีลงท้ายด้วย classloader เดียวกันกับ persistence.xml
Pierluigi Vernetto

@abbas โปรดแสดงpersistence.xmlEclipse ที่สร้างขึ้น
Frans

12

สำหรับผู้ที่ใช้ JPA ใน Spring ตั้งแต่เวอร์ชัน 3.1 เป็นต้นไปคุณสามารถตั้งค่าpackagesToScanคุณสมบัติภายใต้LocalContainerEntityManagerFactoryBeanและกำจัด persistence.xml ได้ทั้งหมด

นี่คือจุดต่ำสุด


ทำงานให้ฉัน! สถานการณ์คือฤดูใบไม้ผลิ 4 + hibernate + jpa2 + maven การทดสอบ JUnit ไม่พบเอนทิตีของฉัน แต่ด้วยการตั้งค่านี้มันได้ผล
SATA

8

คุณสามารถระบุjar-fileเส้นทางขององค์ประกอบไปยังโฟลเดอร์ที่มีคลาสที่คอมไพล์ ตัวอย่างเช่นฉันเพิ่มบางอย่างเช่นนั้นเมื่อฉันเตรียม persistence.xml ในการทดสอบการรวมบางอย่าง:

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

นี่คือสิ่งที่ฉันกำลังมองหา!
xtian

ทำงานร่วมกับ EclipseLink ได้เช่นกัน!
Bombe

8

สำหรับ JPA 2+ นี่เป็นเคล็ดลับ

 <jar-file></jar-file>

สแกนไหทั้งหมดในสงครามเพื่อใส่คำอธิบายประกอบคลาส @Entity


2
คุณมีข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้หรือไม่? ทำงานนี้โดยบังเอิญหรือเขียนไว้ในข้อกำหนด? ขึ้นอยู่กับการนำไปใช้งานหรือไม่?
markus

สแกนเนอร์อยู่ในคลาสขยาย AbstractScannerImpl, hibernate - ไม่รู้ว่ามันเป็นบั๊กหรือฟีเจอร์ขอโทษ
eriskooo

1
ใน Java SE ที่มี Hibernate 5.1.2 ขั้นสุดท้ายวิธีนี้ใช้ไม่ได้ ไฮเบอร์เนตต้องการชื่อไฟล์ jar ( java.lang.IllegalArgumentException: Unable to visit JAR file:)
Stephan

1
ได้ผล! :) ด้วย WildFly 8.2.1 Final + Hibernate 4.3.7 Final
Andreas Dietrich

ขอบคุณคนค้นหามากและนี่คือทางออกที่ดีที่สุด Wildfly10 + Hibernate 5.0.7 ทำงาน
boutta

7

Hibernate ไม่รองรับ <exclude-unlisted-classes>false</exclude-unlisted-classes>ภายใต้ SE (โปสเตอร์อื่นกล่าวถึงสิ่งนี้ใช้ได้กับ TopLink และ EclipseLink)

มีเครื่องมือที่จะสร้างรายการคลาสโดยอัตโนมัติไปยัง persistence.xml เช่นวิซาร์ด Import Database Schema ใน IntelliJ เมื่อคุณมีคลาสเริ่มต้นของโปรเจ็กต์ใน persistence.xml แล้วคุณควรเพิ่ม / ลบคลาสเดี่ยวด้วยตนเองได้อย่างง่ายดายเมื่อโปรเจ็กต์ของคุณดำเนินไป


การตรวจจับเอนทิตีโดยอัตโนมัติใน Java SE ไม่ได้เป็นเพียงส่วนหนึ่งของ JPA แอปพลิเคชันที่ใช้สิ่งนี้ไม่สามารถพกพาได้
Pascal Thivent

4

ไม่แน่ใจว่าคุณกำลังทำสิ่งที่คล้ายกับสิ่งที่ฉันกำลังทำอยู่ แต่ฉันกำลังสร้างซอร์สจาวาจาก XSD โดยใช้ JAXB ในองค์ประกอบแยกโดยใช้ Maven สมมติว่าสิ่งประดิษฐ์นี้เรียกว่า "base-model"

ฉันต้องการนำเข้าอาร์ติแฟกต์นี้ที่มีซอร์สจาวาและรันไฮเบอร์เนตในทุกคลาสในโถอาร์ติแฟกต์ "โมเดลพื้นฐาน" ของฉันและไม่ได้ระบุแต่ละอันอย่างชัดเจน ฉันกำลังเพิ่ม "base-model" เป็นการอ้างอิงสำหรับองค์ประกอบ hibernate ของฉัน แต่ปัญหาคือแท็กใน persistence.xml อนุญาตให้คุณระบุพา ธ สัมบูรณ์เท่านั้น

วิธีที่ฉันได้รับรอบนี้คือการคัดลอกการพึ่งพา jar "แบบจำลองพื้นฐาน" ของฉันอย่างชัดเจนไปยังผบ. เป้าหมายของฉันและดึงเวอร์ชันของมันออกด้วย ดังนั้นในขณะที่ฉันสร้างสิ่งประดิษฐ์ "แบบจำลองพื้นฐาน" ของฉันมันจะสร้าง "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":

            <!-- 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-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>องค์ประกอบเหล่านี้ได้


ฉันใช้persistenceXmlLocationคุณสมบัติในLocalContainerEntityManagerFactoryBeanการตั้งค่าของฉัน แต่การสืบค้นทั้งหมดยังใช้งานได้แม้ว่าฉันจะละ<class>องค์ประกอบก็ตาม บนแอปพลิเคชั่น Spring / Hibernate / Maven แต่ในคำใบ้คุณบอกว่า"เมื่อไม่ใช้ persistenceXmlLocation ฉันสามารถละเว้นองค์ประกอบ <class> เหล่านี้ได้" แต่เป็นอีกทางหนึ่งสำหรับฉัน
โชคดี

@ คุณพูดถูกกว่าเพราะ persistenceXmlLocation แทนที่ packageToScan - ถ้าคุณดูในแหล่งที่มา ดังนั้นอย่าใช้มันเมื่อใช้ packageToScan
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.