Do I need <class> elements in persistence.xml?

159,584

Solution 1

The persistence.xml has a jar-file that you can use. From the 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>

This file defines a persistence unit named OrderManagement, which uses a JTA-aware data source jdbc/MyOrderDB. The jar-file and class elements specify managed persistence classes: entity classes, embeddable classes, and mapped superclasses. The jar-file element specifies JAR files that are visible to the packaged persistence unit that contain managed persistence classes, while the class element explicitly names managed persistence classes.

In the case of Hibernate, have a look at the Chapter2. Setup and configuration too for more details.

EDIT: Actually, If you don't mind not being spec compliant, Hibernate supports auto-detection even in Java SE. To do so, add the hibernate.archive.autodetection property:

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

Solution 2

In Java SE environment, by specification you have to specify all classes as you have done:

A list of all named managed persistence classes must be specified in Java SE environments to insure portability

and

If it is not intended that the annotated persistence classes contained in the root of the persistence unit be included in the persistence unit, the exclude-unlisted-classes element should be used. The exclude-unlisted-classes element is not intended for use in Java SE environments.

(JSR-000220 6.2.1.6)

In Java EE environments, you do not have to do this as the provider scans for annotations for you.

Unofficially, you can try to set <exclude-unlisted-classes>false</exclude-unlisted-classes> in your persistence.xml. This parameter defaults to false in EE and truein SE. Both EclipseLink and Toplink supports this as far I can tell. But you should not rely on it working in SE, according to spec, as stated above.

You can TRY the following (may or may not work in SE-environments):

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

Solution 3

For those running JPA in Spring, from version 3.1 onwards, you can set packagesToScan property under LocalContainerEntityManagerFactoryBean and get rid of persistence.xml altogether.

Here's the low-down

Solution 4

Do I need Class elements in persistence.xml?

No, you don't necessarily. Here is how you do it in Eclipse (Kepler tested):

Right click on the project, click Properties, select JPA, in the Persistence class management tick Discover annotated classes automatically.

enter image description here

Solution 5

You can provide for jar-file element path to a folder with compiled classes. For example I added something like that when I prepared persistence.xml to some integration tests:

 <jar-file>file:../target/classes</jar-file>
Share:
159,584

Related videos on Youtube

Michał Mech
Author by

Michał Mech

Helen's and Lidia's father, Agatha's husband and software engineer from Warsaw, Poland.

Updated on July 08, 2022

Comments

  • Michał Mech
    Michał Mech almost 2 years

    I have very simple persistance.xml file:

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

    and it works.

    But when I remove <class> elements application doesn't see entities (all classes are annotated with @Entity).

    Is there any automatic mechanism to scan for @Entity classes?

  • Michał Mech
    Michał Mech over 14 years
    I see, but the entities (@Entity) are in separate Maven project, so jar-file name can change on every build. I'm looking something to scan all in specific package or classpath. I'm just to lazy to type many, many <class> elements in persistence.xml file.
  • Devanshu Mevada
    Devanshu Mevada over 14 years
    On every build?! I won't even ask why but... you could use filtering to solve this.
  • Michał Mech
    Michał Mech over 14 years
    Not everyone exactly but I want to be resistant to changes.
  • Devanshu Mevada
    Devanshu Mevada over 13 years
    Auto detection of entities in Java SE is just not part of JPA. Applications relying on this are not portable.
  • Laird Nelson
    Laird Nelson over 12 years
    Ancient thread, I know, but have a look at the jpa-maven-plugin.
  • SatA
    SatA about 10 years
    Worked for me! The scenario was spring 4 + hibernate + jpa2 + maven. JUnit testing didn't find my entities but with this setting it did the job.
  • markus
    markus almost 9 years
    do you have more information about this? does this work by accident or is it written in the specification? Is it dependent on the implementation?
  • eriskooo
    eriskooo almost 9 years
    scanner is in class extending AbstractScannerImpl, hibernate - no idea if it's bug or feature, sorry
  • Lucky
    Lucky over 8 years
    I used persistenceXmlLocation property in my LocalContainerEntityManagerFactoryBean settings. But all the queries are working even if I omit the <class> elements. Its on a Spring/Hibernate/Maven application. But in you hint you say that "When not using persistenceXmlLocation I could omit these <class> elements." but its the other way around for me.
  • Artem Novikov
    Artem Novikov over 7 years
    Why upvote? OP doesn't even mentions Eclipse and this answer doesn't show what this Eclipse feature does under the hood so that one could do that wihout an IDE.
  • Artem Novikov
    Artem Novikov over 7 years
    @Ethan you're right, because persistenceXmlLocation overrides packagesToScan - if you look in the sources. So don't use it, when using packagesToScan.
  • Stephan
    Stephan over 7 years
    In Java SE with Hibernate 5.1.2.Final, this solution doesn't work. Hibernate expects a jar filename (java.lang.IllegalArgumentException: Unable to visit JAR file:).
  • med_alpa
    med_alpa over 7 years
    You can use <mapping-file> element (which contains the list of the entities) in persistence.xml, so you can keep the same name of the used files and integrate them in the build of the referenced jars.
  • Andreas Covidiot
    Andreas Covidiot almost 7 years
    works! :) with WildFly 8.2.1.Final + Hibernate 4.3.7.Final
  • Andreas Covidiot
    Andreas Covidiot almost 7 years
    @Artem Novikov: I find this to harsh since often the question arises out of different environments and here we want to help or give hints that are useful! (like for me) It's useful since Eclipse is a common IDE for developing like this and under the hood is not so important, but I guess it will include all relevant workspace projects (e.g. my project is depending on).
  • Andreas Covidiot
    Andreas Covidiot almost 7 years
    <exclude-unlisted-classes>false</exclude-unlisted-classes> did not work with WildFly 8.2.1.Final + Hibernate 4.3.7
  • Andreas Covidiot
    Andreas Covidiot almost 7 years
    <property name="hibernate.archive.autodetection" value="class" /> did not work with WildFly 8.2.1.Final (Hibernate 4.3.7.Final), but this: stackoverflow.com/a/44925520/1915920
  • boutta
    boutta almost 7 years
    Thx man, searched a lot and this is the neatest solution available. Wildfly10 + Hibernate 5.0.7 working.
  • xtian
    xtian over 6 years
    This is what I was looking for!
  • Pierluigi Vernetto
    Pierluigi Vernetto over 6 years
    stackoverflow.com/questions/17951297/… nice trick, but apparently it works only if entities end up in same classloader as the persistence.xml
  • Frans
    Frans almost 6 years
    @abbas Please show the persistence.xml that Eclipse generates.
  • Bombe
    Bombe over 4 years
    Works with EclipseLink, too!
  • Hosseinmp76
    Hosseinmp76 about 4 years
    hibernate.archive.autodetection does not work for me on java se. hibernate 6.0.0.Alpha4
  • Johannes Jander
    Johannes Jander almost 4 years
    There is a more recent fork for the jpa-maven-plugin here: github.com/iSnow/jpa-maven-plugin