wake-up-neo.com

Benötige ich <class> -Elemente in persistence.xml?

Ich habe sehr einfache persistance.xml-Datei:

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

und es funktioniert.

Wenn ich jedoch <class> Elemente entferne, sieht die Anwendung keine Entitäten (alle Klassen sind mit @Entity Beschriftet).

Gibt es einen automatischen Mechanismus, um nach @Entity - Klassen zu suchen?

106
Michał Mech

Die Datei persistence.xml enthält einen jar-file, Den Sie verwenden können. From das Java EE 5 Tutorial :

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

Diese Datei definiert eine Persistenzeinheit mit dem Namen OrderManagement, die eine JTA-fähige Datenquelle jdbc/MyOrderDB Verwendet. Die Elemente jar-file Und class geben verwaltete Persistenzklassen an: Entitätsklassen, einbettbare Klassen und zugeordnete Superklassen. Das Element jar-file Gibt JAR-Dateien an, die für die verpackte Persistenzeinheit sichtbar sind und verwaltete Persistenzklassen enthalten, während das Element class verwaltete Persistenzklassen explizit benennt.

Weitere Informationen zum Ruhezustand finden Sie auch in Kapitel 2. Setup und Konfiguration .

BEARBEITEN: Wenn es Ihnen nichts ausmacht, nicht spezifikationskonform zu sein, unterstützt Hibernate die automatische Erkennung auch in Java SE. Fügen Sie dazu die Eigenschaft hibernate.archive.autodetection Hinzu:

<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>
78
Pascal Thivent

In einer Java SE-Umgebung müssen Sie nach Angabe alle Klassen wie folgt angeben:

Eine Liste aller benannten verwalteten Persistenzklassen muss in Java SE-Umgebungen angegeben werden, um die Portabilität sicherzustellen

und

Wenn nicht beabsichtigt ist, dass die mit Annotationen versehenen Persistenzklassen, die im Stammverzeichnis der Persistenzeinheit enthalten sind, in die Persistenzeinheit aufgenommen werden, sollte das Element exclude-unlisted-classes verwendet werden. Das Element exclude-unlisted-classes ist nicht für die Verwendung in Java SE-Umgebungen vorgesehen.

(JSR-000220 6.2.1.6)

In Java EE-Umgebungen müssen Sie dies nicht tun , da der Anbieter nach Anmerkungen für Sie sucht.

Inoffiziell können Sie versuchen, <exclude-unlisted-classes>false</exclude-unlisted-classes> in Ihrer persistence.xml. Dieser Parameter ist standardmäßig false in EE und true in SE. Sowohl EclipseLink als auch Toplink unterstützen dies, soweit ich das beurteilen kann. Sie sollten sich jedoch nicht darauf verlassen, dass es in SE gemäß der oben angegebenen Spezifikation funktioniert.

Sie können Folgendes VERSUCHEN (funktioniert möglicherweise nicht in SE-Umgebungen):

<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>
43
Mads Mobæk

Benötige ich Klassenelemente in persistence.xml?

Nein, das musst du nicht. So machen Sie es in Eclipse (Kepler-getestet):

Klicken Sie mit der rechten Maustaste auf das Projekt, klicken Sie auf Eigenschaften, wählen Sie JPA im Kontrollkästchen Persistenzklassenverwaltung aus. Mit Anmerkungen versehene Klassen automatisch erkennen.

enter image description here

13
abbas

Wenn Sie JPA in Spring ab Version 3.1 ausführen, können Sie die Eigenschaft packagesToScan unter LocalContainerEntityManagerFactoryBean festlegen und die Datei persistence.xml vollständig entfernen.

Hier ist der Low-Down

11

Hibernate unterstützt <exclude-unlisted-classes>false</exclude-unlisted-classes> Unter SE nicht (ein anderes Poster erwähnte, dass dies mit TopLink und EclipseLink funktioniert).

Es gibt Tools, die automatisch die Klassenliste für persistence.xml generieren, z. Der Assistent zum Importieren eines Datenbankschemas in IntelliJ. Sobald Sie die Anfangsklassen Ihres Projekts in persistence.xml haben, sollte es einfach sein, einzelne Klassen im Verlauf Ihres Projekts von Hand hinzuzufügen/zu entfernen.

7

Sie können für jar-file Elementpfad zu einem Ordner mit kompilierten Klassen. Zum Beispiel habe ich so etwas hinzugefügt, als ich persistence.xml für einige Integrationstests vorbereitet habe:

 <jar-file>file:../target/classes</jar-file>
7
Arek Trzepacz

für JPA 2+ ist dies der Trick

 <jar-file></jar-file>

scannen Sie alle Gläser im Krieg nach kommentierten @Entity-Klassen

7
eriskooo

Ich bin mir nicht sicher, ob Sie etwas Ähnliches tun wie ich, aber ich generiere eine Menge Quellcode Java von einer XSD mit JAXB in einer separaten Komponente mit Maven. Sagen wir, dieses Artefakt heißt "Basismodell"

Ich wollte dieses Artefakt importieren, das die Java) -Quelle enthält, und über alle Klassen in meinem Artefakt-Jar "Basismodell" den Ruhezustand ausführen und nicht jede explizit angeben. Ich füge "Basismodell" als Abhängigkeit hinzu Für meine Ruhezustand-Komponente ist das Tag in persistence.xml aber das Problem, mit dem Sie nur absolute Pfade angeben können.

Die Art und Weise, wie ich damit umgegangen bin, besteht darin, meine "Basismodell" -Jar-Abhängigkeit explizit in mein Zielverzeichnis zu kopieren und auch die Version davon zu entfernen. Wenn ich also mein "Basismodell" -Artefakt erstelle, wird "base-model-1.0-SNAPSHOT.jar" generiert, und der Schritt "copy-resources" kopiert es als "base-model.jar".

Also in deinem Pom für den Ruhezustand:

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

Dann rufe ich das Hibernate-Plugin in der nächsten Phase "Prozessklassen" auf:

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

und schließlich kann ich in meiner persistence.xml die Position des Glases explizit wie folgt festlegen:

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

und fügen Sie die Eigenschaft hinzu:

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

Es ist keine Lösung, sondern ein Hinweis für diejenigen, die Spring verwenden:

Ich habe versucht, org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean Mit der Einstellung von persistenceXmlLocation zu verwenden, musste jedoch die <class> - Elemente angeben (auch wenn persistenceXmlLocation nur auf META-INF/persistence.xml).

Wenn nichtpersistenceXmlLocation verwendet, könnte ich diese <class> - Elemente weglassen.

3
Ethan Leroy

Ich bin nicht sicher, ob diese Lösung den Spezifikationen entspricht, aber ich denke, ich kann sie für andere freigeben.

abhängigkeitsbaum

my-entity.jar

Enthält nur Entitätsklassen. Nein META-INF/persistence.xml.

my-services.jar

Kommt drauf an my-entities. Enthält nur EJBs.

my-resources.jar

Kommt drauf an my-services. Enthält Ressourcenklassen und META-INF/persistence.xml.

probleme

  • Wie können wir <jar-file/> Element in my-resources als version-postfixierter Artefaktname einer transienten Abhängigkeit?
  • Wie können wir das <jar-file/> Der Wert des Elements und der Wert der tatsächlichen vorübergehenden Abhängigkeit?

lösung

direkte (redundante?) Abhängigkeit und Ressourcenfilterung

Ich habe eine Eigenschaft und eine Abhängigkeit in 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>

Holen Sie sich jetzt die persistence.xml bereit zum filtern

<?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 Plugin

Mit der dependencyConvergence -Regel können wir sicherstellen, dass die my-entities 'Version ist sowohl direkt als auch transitiv gleich.

<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>
2
Jin Kwon

Nicht unbedingt in allen Fällen.

Ich benutze Jboss 7.0.8 und Eclipselink 2.7.0. In meinem Fall, um Entitäten zu laden, ohne diese in persistence.xml hinzuzufügen, habe ich die folgende Systemeigenschaft in Jboss Standalone XML hinzugefügt:

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

0
Gandhi