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

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?


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>

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>

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


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


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>