5.2. Class Annotations

5.2.1. Entity
5.2.2. IdClass
5.2.3. MappedSuperclass
5.2.4. Embeddable
5.2.5. EntityListeners
5.2.6. Example

The following metadata annotations apply to persistent class declarations.

5.2.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 EJBQL. Defaults to the unqualified name of the entity class.

The equivalent XML element is entity which understands 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 5.3, “Field and Property Annotations”.

[Note]Note

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

5.2.2. IdClass

As we discussed in Section 4.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 understands the following attribute:

  • class: This required attribute lists the class name for the primary key class.

5.2.3. MappedSuperclass

An MappedSuperclass 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.

The equivalent XML element is mapped-superclass which understands the following attributes:

[Note]Note

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

5.2.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 which understands the following attributes:

[Note]Note

Kodo allows a persistent class to be both an entity and an embeddable class. Instances of the class will act as entites 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 Kodo, simply add both the @Entity and the @Embeddable annotations to the class.

5.2.5. EntityListeners

Persistent classes can define listeners for various events. These listeners can be of any class as long as it has an empty constructor and defines one or more annotated callback methods. For each class listed as a listener, a new instance will will be created. This instance will then have any callback methods invoked appropriately for the given event. The callback methods should return void and take in a generic Object argument of the persistent type. The single property of this annotation is:

  • Class[] value: The list of classes to instantiate as entity listeners.

For more details on entity listeners, see Section 4.3, “Lifecycle Callbacks”.

The equivalent XML element is id-class which understands the following attribute:

  • class: This required attribute lists the class name for the primary key class.

5.2.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 metadata would be:


<entity-mappings>
    <mapped-superclass class="org.mag.subscribe.Document">
        <!-- .... -->
    </mapped-superclass>
    <entity class="org.mag.Magazine">
        <id-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>