Ai-je besoin d'éléments dans la persistance.xml?
j'ai une persistance très simple.fichier 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>
et ça marche.
mais quand je supprime <class>
l'application éléments ne voit pas les entités (toutes les classes sont annotées avec @Entity
).
y a-t-il un mécanisme automatique pour rechercher les classes @Entity
?
10 réponses
La persistance.xml a un jar-file
que vous pouvez utiliser. De le tutoriel 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>
Ce fichier définit une unité de persistance
nommé OrderManagement
, qui utilise un
JTA-courant de la source de données jdbc/MyOrderDB
. Les éléments jar-file
et class
précisent les classes gérées de persistance: les classes d'entités, les classes intégrables et les superclasses cartographiées. L'élément jar-file
spécifie JAR l'élément class
nomme explicitement les classes de persistance gérées.
dans le cas D'hibernation, consultez le chapitre 2. Setup et configuration aussi pour plus de détails.
EDIT: en fait, si cela ne vous dérange pas de ne pas être conforme spec, Hibernate prend en charge la détection automatique même en Java SE. Pour ce faire, ajoutez la hibernate.archive.autodetection
propriété:
<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>
dans environnement Java SE, par spécification, vous devez spécifier toutes les classes comme vous l'avez fait:
Une liste de tous les noms de classes de persistance gérée doit être spécifié dans les environnements Java SE pour garantir la portabilité
et
s'il n'est pas prévu que les classes de persistance annotées contenues dans la racine de l'Unité de persistance soient l'Unité de persistance, l'élément exclure-non-énuméré-classes doit être utilisée. L'élément exclude-unlisted-classes n'est pas destiné à être utilisé dans les environnements Java SE.
(JSR-000220 6.2.1.6)
dans environnements Java EE, vous ne pas avoir à le faire que le fournisseur scanne pour les annotations pour vous.
Officieusement, vous pouvez essayer de mettre <exclude-unlisted-classes>false</exclude-unlisted-classes>
dans votre persistance.XML. Ce paramètre par défaut, false
dans EE et true
dans SE. Les deux EclipseLink et Toplink supporte ceci autant que je peux dire. Mais vous ne devez pas compter sur elle travaillant en SE, Selon les spécifications, comme indiqué ci-dessus.
Vous pouvez ESSAYER ce qui suit (peut ou peut ne pas fonctionner dans SE-environnements):
<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>
ai-je besoin d'éléments de Classe dans la persistance.xml?
non, pas nécessairement. Voici comment vous le faites dans Eclipse (testé par Kepler):
clic droit sur le projet, clic propriétés , sélectionner JPA , dans le gestion des classes de persistance tick découvrir automatiquement les classes annotées .
pour ceux qui exécutent JPA au printemps, à partir de la version 3.1, Vous pouvez définir packagesToScan
propriété sous LocalContainerEntityManagerFactoryBean
et se débarrasser de la persistance.xml dans l'ensemble.
pour JPA 2+ cela fait l'affaire
<jar-file></jar-file>
scanner toutes les jarres en guerre pour les classes d'entités annotées
Hibernate ne prend pas en charge <exclude-unlisted-classes>false</exclude-unlisted-classes>
en vertu de la SE, (une autre affiche mentionné cela fonctionne avec TopLink et EclipseLink).
il y a des outils qui vont générer automatiquement la liste des classes de persistance.xml par exemple, le magicien de schéma de base de données D'importation dans IntelliJ. Une fois que vous avez obtenu les classes initiales de votre projet dans la persistance.xml il devrait être simple d'Ajouter / Supprimer des classes individuelles à la main au fur et à mesure que votre projet progresse.
vous pouvez fournir le chemin de l'élément jar-file
vers un dossier avec des classes compilées. Par exemple, j'ai ajouté quelque chose comme ça quand j'ai préparé la persistance.xml pour certains tests d'intégration:
<jar-file>file:../target/classes</jar-file>
pas sûr si vous faites quelque chose de similaire à ce que je fais, mais Im générant une charge de java source à partir D'un XSD en utilisant JAXB dans un composant séparé en utilisant Maven. Disons que cet artefact est appelé "base-model "
je voulais importer cet artéfact contenant la source java et exécuter l'hibernation sur toutes les classes dans mon pot d'artéfacts" de Base-model " et ne pas les spécifier explicitement. J'ajoute "base-model" comme dépendance pour ma composante d'hibernation mais le problème est la balise dans la persistance.xml permet seulement de spécifier des chemins absolus.
la façon dont je l'ai contourné est de copier ma dépendance jar" base-model " explicitement à mon dir cible et aussi de supprimer la version de celui-ci. Alors que si je construis mon artéfact " base-model "il génère" base-model-1.0-SNAPSHOT.jar", l'étape copy-resources le copie en tant que " base-model.pot."
donc dans votre pom pour le composant 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>
alors j'appelle le plugin hibernate dans la phase suivante "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>
et enfin dans ma persistance.xml je peux définir explicitement l'emplacement du bocal ainsi:
<jar-file>target/dependency/base-model.jar</jar-file>
et ajouter la propriété:
<property name="hibernate.archive.autodetection" value="class, hbm"/>
ce n'est pas une solution mais une indication pour ceux qui utilisent le ressort:
j'ai essayé d'utiliser org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
avec le réglage persistenceXmlLocation
mais avec cela j'ai dû fournir les éléments <class>
(même si le persistenceXmlLocation
vient de pointer vers META-INF/persistence.xml
).
quand pas en utilisant persistenceXmlLocation
je pourrais omettre ces éléments <class>
.
Je ne suis pas sûr que cette solution est sous la spécification, mais je pense que je peux partager pour les autres.
arbre de dépendance
mon-entités.jar
contient uniquement des classes d'entités. Pas de META-INF/persistence.xml
.
my-services.jar
dépend de my-entities
. Contient des Ejb.
mes ressources.jar
dépend de my-services
. Contenir ressources des classes et des META-INF/persistence.xml
.
problèmes
- Comment Pouvons-nous spécifier
<jar-file/>
élément dansmy-resources
comme la version-artefact postfixé nom d'une dépendance transitoire? - Comment synchroniser la valeur de l'élément
<jar-file/>
et celle de la dépendance transitoire réelle?
solution
"1519180920 directe" (un pléonasme?) filtrage des dépendances et des ressources j'ai mis une propriété et une dépendance dans 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>
maintenant obtenir le persistence.xml
prêt pour être filtré
<?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""
avec la règle dependencyConvergence
, nous pouvons assurer que la version my-entities
' est la même dans les deux direct et transitif.
<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>