112 votes

Ai-je besoin d'éléments <class> dans le fichier persistence.xml ?

J'ai un fichier persistance.xml très simple :

<?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 retire <class> L'application ne voit pas les entités (toutes les classes sont annotées avec le symbole @Entity ).

Existe-t-il un mécanisme automatique pour rechercher @Entity classes ?

80voto

Pascal Thivent Points 295221

Le fichier persistence.xml comporte 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ée OrderManagement qui utilise un source de données compatible JTA jdbc/MyOrderDB . Le site jar-file y class spécifient les classes de persistance gérées : classes d'entités, classes intégrables et superclasses mappées. Le site jar-file spécifie les fichiers JAR visibles par l'unité de persistance packagée qui contiennent des classes de persistance gérées, tandis que l'élément class nomme explicitement les classes de persistance gérées.

Dans le cas d'Hibernate, jetez un coup d'œil à l'onglet Chapitre 2. Mise en place et configuration également pour plus de détails.

EDIT : En fait, si cela ne vous dérange pas de ne pas être conforme aux spécifications, Hibernate prend en charge l'autodétection même en Java SE. Pour ce faire, ajoutez l'option 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>

13 votes

Je vois, mais les entités (@Entity) sont dans un projet Maven séparé, donc le nom du fichier jar peut changer à chaque construction. Je cherche quelque chose pour tout scanner dans un package ou classpath spécifique. Je suis trop paresseux pour taper de très nombreux éléments <class> dans le fichier persistence.xml.

0 votes

Sur chaque construction ? ! Je ne vais même pas demander pourquoi mais... vous pourriez utiliser le filtrage pour résoudre ce problème.

0 votes

Pas tout le monde exactement, mais je veux être résistant aux changements.

44voto

Mads Mobæk Points 9515

En environnement Java SE, par spécification vous devez spécifier toutes les classes comme vous l'avez fait :

Une liste de toutes les classes de persistance gérées nommées doit être spécifiée dans les environnements Java SE pour assurer 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 incluses dans l'unité de persistance, l'élément exclude-unlisted-classes doit être utilisé. L'élément exclude-unlisted-classes n'est pas destiné à être utilisé dans les environnements Java SE.

(JSR-000220 6.2.1.6)

En environnements Java EE, vous n'avez pas Vous n'avez pas à le faire, car le fournisseur recherche les annotations pour vous.

De manière non officielle, vous pouvez essayer de définir <exclude-unlisted-classes>false</exclude-unlisted-classes> dans votre fichier persistence.xml. Ce paramètre a pour valeur par défaut false en EE et true en SE. Les deux sites EclipseLink y Toplink soutient ceci pour autant que je puisse dire. Mais vous ne devriez pas compter sur le fait que cela fonctionne dans SE, selon les spécifications, comme indiqué ci-dessus.

Vous pouvez ESSAYER ce qui suit (peut ou non fonctionner dans les environnements 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 votes

<exclude-unlisted-classes>false</exclude-unlisted-classes> ne fonctionne pas avec WildFly 8.2.1.Final + Hibernate 4.3.7

12voto

abbas Points 483

Ai-je besoin d'éléments de classe dans le fichier persistence.xml ?

Non, pas nécessairement. Voici comment procéder dans Eclipse (testé sur Kepler) :

Cliquez à droite sur le projet, cliquez sur Propriétés , sélectionnez JPA dans le Gestion des classes de persistance tique Découvrir automatiquement les classes annotées .

enter image description here

9 votes

Pourquoi upvote ? L'OP ne mentionne même pas Eclipse et cette réponse ne montre pas ce que cette fonctionnalité Eclipse fait sous le capot pour que l'on puisse faire cela sans IDE.

2 votes

@Artem Novikov : Je trouve cela un peu dur car souvent la question se pose dans des environnements différents et ici nous voulons aider ou donner des conseils qui sont utiles ! (comme pour moi) C'est utile car Eclipse est un IDE commun pour développer comme ça et sous le capot n'est pas si important, mais je suppose que cela inclura tous les projets pertinents de l'espace de travail (par exemple, mon projet dépend de).

0 votes

stackoverflow.com/questions/17951297/ belle astuce, mais apparemment cela ne fonctionne que si les entités se retrouvent dans le même classloader que le persistence.xml

12voto

Pour ceux qui exécutent JPA dans Spring, à partir de la version 3.1, vous pouvez configurer packagesToScan biens sous LocalContainerEntityManagerFactoryBean et se débarrasser complètement de persistence.xml.

Voici les grandes lignes

0 votes

Cela a marché pour moi ! Le scénario était spring 4 + hibernate + jpa2 + maven. Les tests JUnit n'ont pas trouvé mes entités mais avec ce paramètre, cela a fait le travail.

7voto

Chuck Stephanski Points 209

Hibernate ne supporte pas <exclude-unlisted-classes>false</exclude-unlisted-classes> sous SE, (un autre poster a mentionné que cela fonctionne avec TopLink et EclipseLink).

Il existe des outils qui génèrent automatiquement la liste des classes dans persistence.xml, par exemple l'assistant Import Database Schema d'IntelliJ. Une fois que les classes initiales de votre projet sont dans persistence.xml, il devrait être simple d'ajouter/supprimer des classes individuelles à la main au fur et à mesure que votre projet progresse.

0 votes

La détection automatique des entités dans Java SE ne fait tout simplement pas partie de JPA. Les applications qui en dépendent ne sont pas portables.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X