6.4. Metadata Extensions

6.4.1. Class Extensions Fetch Groups Data Cache Detached State Lock Groups Auditable
6.4.2. Field Extensions Dependent Load Fetch Group LRS Order-By Inverse-Logical Lock Group Read-Only Type Externalizer Factory External Values
6.4.3. Example

Kodo extends standard metadata to allow you to access advanced Kodo functionality. This section covers persistence metadata extensions; we discuss mapping metadata extensions in Section 7.9, “Mapping Extensions”. All metadata extensions are optional; Kodo will rely on its defaults when no explicit data is provided.

In JDO metadata, Kodo extensions are expresses with standard JDO extension elements. All Kodo extensions use a vendor-name of kodo. The next sections present a list of the available class and field element extension keys.

6.4.1. Class Extensions

Kodo recognizes the following class extensions: Fetch Groups

JDO standardizes fetch group definition with the the fetch-group XML metadata element. Fetch groups, however, are not part of the JPA standard. The org.apache.openjpa.persistence.FetchGroups and org.apache.openjpa.persistence.FetchGroup annotations allow you to define fetch groups in your JPA entities. Section 5.6, “Fetch Groups” discusses Kodo's support for fetch groups in general; see Section 5.6.1, “Custom Fetch Groups” for how to use these annotations in particular. Data Cache

Section 10.1, “Data Cache” examines caching in Kodo. Metadata extensions allow individual classes to override system caching defaults.

Kodo JPA defines the org.apache.openjpa.persistence.DataCache annotation for caching information. This annotation has the following properties:

  • boolean enabled: Whether to cache data for instances of the class. Defaults to true for base classes, or the superclass value for subclasses. If you set this property to false, all other properties are ignored.

  • String name: Place data for instances of the class in a named cache. By default, instance data is placed in the same cache as superclass data, or the default cache configured through the kodo.DataCache configuration property for base classes.

  • int timeout: The number of milliseconds data for the class remains valid. Use -1 for no timeout. Defaults to the kodo.DataCacheTimeout property value.

Kodo JDO uses the data-cache and data-cache-timeout XML extension keys to specify class caching information. The data-cache-timeout key sets the number of milliseconds cached data for an instance remains valid. A value of -1 means never to expire instance data. This extension overrides the kodo.DataCacheTimeout configuration property.

The data-cache key accepts the following values:

  • true: Use the default cache, as configured by the kodo.DataCache configuration property. This is the default when no extension is given, unless a superclass names a different cache.

  • false: Data for instances of this class should not be cached.

  • <cache-name>: Place data for instances of this class into the cache with name <cache-name>. Detached State

The Kodo enhancer may add a synthetic field to detachable classes to hold detached state (see Section 11.1.3, “Defining the Detached Object Graph” for details). You can instead declare your own detached state field or supress the creation of a detached state field altogether. In the latter case, your class must not use datastore identity, and should declare a version field to detect optimistic concurrency errors during detached modifications.

Kodo JPA defines the org.apache.openjpa.persistence.DetachedState annotation for controlling detached state. When used to annotate a class, DetachedState recognizes the following properties:

  • boolean enabled: Set to false to suppress the use of detached state.

  • String fieldName: Use this property to declare your own detached state field. The field must be of type Object. Typically this property is only used if the field is inherited from a non-persisted superclass. If the field is declared in your entity class, you will typically annotate the field directly, as described below.

If you declare your own detached state field, you can annotate that field with DetachedState directly, rather than placing the annotation at the class level and using the fieldName property. When placed on a field, DetachedState acts as a marker annotation; it does not recognize any properties. Your annotated field must be of type Object.

The JDO detached-state-field extension key names the Object field used to store an object's detached state information. Set this extension to the name of a field in your class, or to false to disable the use of detached state. Lock Groups

Kodo requires you to pre-declare subclass lock groups in the least-derived mapped class. The JPA kodo.persistence.LockGroups annotation accepts an array of lock group names. The JDO lock-groups XML extension key accepts a string of comma-separated lock group names. For details on lock groups, see Section 5.8.1, “Lock Groups and Subclasses”. Auditable

Reserved for future use.

6.4.2. Field Extensions

Kodo recognizes the following field extensions: Dependent

In a dependent relation, the referenced object is deleted whenever the owning object is deleted, or whenever the relation is severed by nulling or resetting the owning field. For example, if the Magazine.coverArticle field is marked dependent, then setting Magazine.coverArticle to a new Article instance will automatically delete the old Article stored in the field. Similarly, deleting a Magazine object will automatically delete its current cover Article. You can prevent an orphaned dependent object from being deleted by assigning it to another relation in the same transaction.

JDO standardizes support for dependent relations with the dependent attribute of the XML field element, and the dependent-element, dependent-key, and dependent-value attribues of the collection and map elements. Kodo JPA offers a family of marker annotations to denote dependent relations in JPA entities:  Load Fetch Group

JDO standardizes the concept of a load fetch group definition with the load-fetch-group XML metadata attribute. Fetch groups, however, are not part of the JPA standard. The org.apache.openjpa.persistence.LoadFetchGroup annotation specifies a field's load fetch group. Section 5.6, “Fetch Groups” discusses Kodo's support for fetch groups in general; see Section 5.6.1, “Custom Fetch Groups” for how to use this annotation in particular. LRS

This boolean extension, denoted by the JPA org.apache.openjpa.persistence.LRS annotation, or the JDO lrs metadata extension key, indicates that a field should use Kodo's special large result set collection or map proxies. A complete description of large result set proxies is available in Section, “Large Result Set Proxies”. Order-By

The JPA Overview's Section 5.2.12, “Order By” describes JPA's OrderBy annotation for loading the elements of collection fields in a prescribed order. The JDO order-by metadata extension serves the same function. Ordering syntax is as follows:

#element|<field name>[ asc|ascending|desc|descending][, ...]

The token #element represents the element value. Simple element types such as strings and primitive wrappers are sorted based on their natural ordering. If the collection holds persistent objects, its elements are sorted based on the natural ordering of the objects' primary key values. By substituting a field name for the #element token, you can order a collection of persistent objects by an arbitrary field in the related type, rather than by primary key.

The field name or #element token may be followed by the keywords asc/ascending or desc/descending in either all-upper or all-lower case to mandate ascending and descending order. If the direction is omitted, Kodo defaults to ascending order.

Note that the defined ordering is only applied when the collection is loaded from the datastore. It is not maintained by Kodo as you modify the collection in memory.

The following ordering string orders a collection by its element values in descending order:

"#element desc"

The following ordering string orders a collection of Author objects by each author's last name in ascending order. If two last names are equal, the authors are ordered by first name in ascending order.

"firstName, lastName" Inverse-Logical

This extension names the inverse field in a logical bidirectional relation. To create a logical bidrectional relation in Kodo JPA, use the org.apache.openjpa.persistence.InverseLogical annotation. To create a logical bidrectional relation in Kodo JDO, use the inverse-logical XML extension key. We discuss logical bidirectional relations and this extension in detail in Section 5.4, “Managed Inverses”. Lock Group

Lock groups allow for fine-grained optimistic locking concurrency. Use Kodo JPA's kodo.persistence.LockGroup annotation or Kodo JDO's lock-group extension key to name the lock group for a field. You can exclude a field from optimistic locking with a value of none. We discuss lock groups and this extension further in Section 5.8, “Lock Groups”. Read-Only

The read-only extension makes a field unwritable. The extension only applies to existing persistent objects; new object fields are always writeable.

To mark a field read-only in JPA metadata, set the org.apache.openjpa.persistence.ReadOnly annotation to a org.apache.openjpa.persistence.UpdateAction enum value. The UpdateAction enum includes:

  • UpdateAction.IGNORE: Updates to the field are completely ignored. The field is not considered dirty. The new value will not even get stored in the Kodo data cache.

  • UpdateAction.RESTRICT: Any attempt to change the field will result in an immediate exception.

To mark a field read-only in JDO metadata, set the read-only extension key to one of the following values:

  • ignore: Updates to the field are completely ignored. The field is not considered dirty. The new value will not even get stored in the Kodo data cache.

  • restrict: Any attempt to change the field will result in an immediate exception. Type

Kodo has three levels of support for relations:

  1. Relations that hold a reference to an object of a concrete persistent class are supported by storing the primary key values of the related instance in the database.

  2. Relations that hold a reference to an object of an unknown persistent class are supported by storing the stringified identity value of the related instance. This level of support does not allow queries across the relation.

  3. Relations that hold an unknown object or interface. The only way to support these relations is to serialize their value to the database. This does not allow you to query the field, and is not very efficient.

Clearly, when you declare a field's type to be another persistence-capable class, Kodo uses level 1 support. By default, Kodo assumes that any interface-typed fields you declare will be implemented only by other persistent classes, and assigns interfaces level 2 support. The exception to this rule is the java.io.Serializable interface. If you declare a field to be of type Serializable, Kodo lumps it together with java.lang.Object fields and other non-interface, unrecognized field types, which are all assigned level 3 support.

With Kodo's type family of metadata extensions, you can control the level of support given to your unknown/interface-typed fields. Setting the value of this extension to Entity in JPA or PersistenceCapable in JDO indicates that the field value will always be some persistent object, and gives level 2 support. Setting the value of this extension to the class of a concrete persistent type is even better; it gives you level 1 support (just as if you had declared your field to be of that type in the first place). Setting this extension to Object uses level 3 support. This is useful when you have an interface relation that may not hold other persistent objects (recall that Kodo assumes interface fields will always hold persistent instances by default).

This extension is also used with Kodo's externalization feature, described in Section 5.5.5, “Externalization”.

Kodo JPA defines the following type annotations for field values, collection, array, and map elements, and map keys, respectively:

Kodo JDO defines the following type extension keys for field values, collection and array elements, map entry keys, and map entry values, respectively:

  • type

  • element-type

  • key-type

  • value-type Externalizer

The JPA org.apache.openjpa.persistence.Externalizer annotation or JDO externalizer extension key names a method to transform a field value into a value of another type. See Section 5.5.5, “Externalization” for details. Factory

The JPA org.apache.openjpa.persistence.Factory annotation or JDO factory extension key names a method to re-create a field value from its externalized form. See Section 5.5.5, “Externalization” for details. External Values

The JPA org.apache.openjpa.persistence.ExternalValues annotation or JDO external-values extension key declares values for transformation of simple fields to different constant values in the datastore. See Section, “External Values” for details.

6.4.3. Example

The following example shows you how to specify extensions in metadata.

Example 6.4. Kodo Metadata Extensions


import kodo.persistence.*;
import org.apache.openjpa.persistence.*;

public class Magazine
    private Collection<Subscriber> subscribers;

    @ExternalValues({"true=1", "false=2"})
    private boolean weekly;

    @OrderBy("#element DESC")
    private List<String> subtitles;



    <package name="org.mag">
        <class name="Magazine">
            <extension vendor-name="kodo" key="data-cache" value="false"/>
            <field name="subscribers">
                <collection element-type="Subscriber"/>
                <extension vendor-name="kodo" key="lrs" value="true"/>
                <extension vendor-name="kodo" key="lock-group" value="none"/>
            <field name="weekly">
                <extension vendor-name="kodo" key="external-values" 
                <extension vendor-name="kodo" key="type" value="int"/>
            <field name="subtitles">
                <collection element-type="string"/>
                <extension vendor-name="kodo" key="order-by" 
                    value="#element desc"/>


Skip navigation bar   Back to Top