Chapter 5. Metadata
Prev | Part 2. Java Persistence API | Next

## Chapter 5. Metadata

JPA requires that you accompany each persistent class with persistence metadata. This metadata serves three primary purposes:

1. To identify persistent classes.

2. To override default JPA behavior.

3. To provide the JPA implementation with information that it cannot glean from simply reflecting on the persistent class.

Persistence metadata is specified using either the Java annotations defined in the `jakarta.persistence` package, XML mapping files, or a mixture of both. In the latter case, XML declarations override conflicting annotations. If you choose to use XML metadata, the XML files must be available at development and runtime, and must be discoverable via either of two strategies:

1. In a resource named `orm.xml` placed in a `META-INF` directory within a directory in your classpath or within a jar archive containing your persistent classes.

2. Declared in your `persistence.xml` configuration file. In this case, each XML metadata file must be listed in a `mapping-file` element whose content is either a path to the given file or a resource location available to the class' class loader.

We describe the standard metadata annotations and XML equivalents throughout this chapter. The full schema for XML mapping files is available in Section 3, “ XML Schema ”. JPA also standardizes relational mapping metadata and named query metadata, which we discuss in Chapter 13, Mapping Metadata and Section 1.11, “ Named Queries ” respectively.

### Note

OpenJPA defines many useful annotations beyond the standard set. See Section 3, “ Additional JPA Metadata ” and Section 4, “ Metadata Extensions ” in the Reference Guide for details. There are currently no XML equivalents for these extension annotations.

### Note

Persistence metadata may be used to validate the contents of your entities prior to communicating with the database. This differs from mapping meta data which is primarily used for schema generation. For example if you indicate that a relationship is not optional (e.g. @Basic(optional=false)) OpenJPA will validate that the variable in your entity is not null before inserting a row in the database.

Through the course of this chapter, we will create the persistent object model above.

## 1. Class Metadata

The following metadata annotations and XML elements apply to persistent class declarations.

### 1.1. Entity

The `Entity` annotation denotes an entity class. All entity classes must have this annotation. The `Entity` annotation takes one optional property:

- `String name`: Name used to refer to the entity in queries. Must not be a reserved literal in JPQL. Defaults to the unqualified name of the entity class.

The equivalent XML element is `entity`. It has the following attributes:

- `class`: The entity class. This attribute is required.

- `name`: Named used to refer to the class in queries. See the name property above.

- `access`: The access type to use for the class. Must either be `FIELD` or `PROPERTY`. For details on access types, see Section 2, “ Field and Property Metadata ”.

### Note

OpenJPA uses a process called enhancement to modify the bytecode of entities for transparent lazy loading and immediate dirty tracking. See Section 2, “ Enhancement ” in the Reference Guide for details on enhancement.

### 1.2. Id Class

As we discussed in Section 2.1, “ Identity Class ”, entities with multiple identity fields must use an identity class to encapsulate their persistent identity. The `IdClass` annotation specifies this class. It accepts a single `java.lang.Class` value.

The equivalent XML element is `id-class`, which has a single attribute:

- `class`: Set this required attribute to the name of the identity class.

### 1.3. Mapped Superclass

A mapped superclass is a non-entity class that can define persistent state and mapping information for entity subclasses. Mapped superclasses are usually abstract. Unlike true entities, you cannot query a mapped superclass, pass a mapped superclass instance to any `EntityManager` or `Query` methods, or declare a persistent relation with a mapped superclass target. You denote a mapped superclass with the `MappedSuperclass` marker annotation.

The equivalent XML element is `mapped-superclass`. It expects the following attributes:

- `class`: The entity class. This attribute is required.

- `access`: The access type to use for the class. Must either be `FIELD` or `PROPERTY`. For details on access types, see Section 2, “ Field and Property Metadata ”.

### Note

OpenJPA allows you to query on mapped superclasses. A query on a mapped superclass will return all matching subclass instances. OpenJPA also allows you to declare relations to mapped superclass types; however, you cannot query across these relations.

### 1.4. Embeddable

The `Embeddable` annotation designates an embeddable persistent class. Embeddable instances are stored as part of the record of their owning instance. All embeddable classes must have this annotation.

A persistent class can either be an entity or an embeddable class, but not both.

The equivalent XML element is `embeddable`. It understands the following attributes:

- `class`: The entity class. This attribute is required.

- `access`: The access type to use for the class. Must either be `FIELD` or `PROPERTY`. For details on access types, see Section 2, “ Field and Property Metadata ”.

### Note

OpenJPA allows a persistent class to be both an entity and an embeddable class. Instances of the class will act as entities when persisted explicitly or assigned to non-embedded fields of entities. Instances will act as embedded values when assigned to embedded fields of entities.

To signal that a class is both an entity and an embeddable class in OpenJPA, simply add both the `@Entity` and the `@Embeddable` annotations to the class.

### 1.5. EntityListeners

An entity may list its lifecycle event listeners in the `EntityListeners` annotation. This value of this annotation is an array of the listener `Class` es for the entity. The equivalent XML element is `entity-listeners`. For more details on entity listeners, see Section 3, “ Lifecycle Callbacks ”.

### 1.6. Example

Here are the class declarations for our persistent object model, annotated with the appropriate persistence metadata. Note that `Magazine` declares an identity class, and that `Document` and `Address` are a mapped superclass and an embeddable class, respectively. `LifetimeSubscription` and `TrialSubscription` override the default entity name to supply a shorter alias for use in queries.

Example 5.1. Class Metadata

    package org.mag;

    @Entity
    @IdClass(Magazine.MagazineId.class)
    public class Magazine {
        ...

        public static class MagazineId {
            ...
        }
    }

    @Entity
    public class Article {
        ...
    }

    package org.mag.pub;

    @Entity
    public class Company {
        ...
    }

    @Entity
    public class Author {
        ...
    }

    @Embeddable
    public class Address {
        ...
    }

    package org.mag.subscribe;

    @MappedSuperclass
    public abstract class Document {
        ...
    }

    @Entity
    public class Contract
        extends Document {
        ...
    }

    @Entity
    public class Subscription {
        ...

        @Entity
        public static class LineItem
            extends Contract {
            ...
        }
    }

    @Entity(name="Lifetime")
    public class LifetimeSubscription
        extends Subscription {
        ...
    }

    @Entity(name="Trial")
    public class TrialSubscription
        extends Subscription {
        ...
    }

The equivalent declarations in XML:

    <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
        version="1.0">
        <mapped-superclass class="org.mag.subscribe.Document">
            ...
        </mapped-superclass>
        <entity class="org.mag.Magazine">
            <id-class class="org.mag.Magazine$MagazineId"/>
            ...
        </entity>
        <entity class="org.mag.Article">
            ...
        </entity>
        <entity class="org.mag.pub.Company">
            ...
        </entity>
        <entity class="org.mag.pub.Author">
            ...
        </entity>
        <entity class="org.mag.subscribe.Contract">
            ...
        </entity>
        <entity class="org.mag.subscribe.LineItem">
            ...
        </entity>
        <entity class="org.mag.subscribe.LifetimeSubscription" name="Lifetime">
            ...
        </entity>
        <entity class="org.mag.subscribe.TrialSubscription" name="Trial">
            ...
        </entity>
        <embeddable class="org.mag.pub.Address">
            ...
        </embeddable>
    </entity-mappings>

Prev | Up | Next
4. Conclusions | Home | 2. Field and Property Metadata