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?
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>
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>
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.
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.
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.
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>
für JPA 2+ ist dies der Trick
<jar-file></jar-file>
scannen Sie alle Gläser im Krieg nach kommentierten @Entity-Klassen
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"/>
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.
Ich bin nicht sicher, ob diese Lösung den Spezifikationen entspricht, aber ich denke, ich kann sie für andere freigeben.
Enthält nur Entitätsklassen. Nein META-INF/persistence.xml
.
Kommt drauf an my-entities
. Enthält nur EJBs.
Kommt drauf an my-services
. Enthält Ressourcenklassen und META-INF/persistence.xml
.
<jar-file/>
Element in my-resources
als version-postfixierter Artefaktname einer transienten Abhängigkeit?<jar-file/>
Der Wert des Elements und der Wert der tatsächlichen vorübergehenden Abhängigkeit?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>
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>
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"/>