6.2. JDO Metadata Extensions
Prev | Chapter 6. Metadata | Next

## 6.2. JDO Metadata Extensions

Kodo JDO takes advantage of JDO metadata's built-in extension mechanism to allow you to specify persistence-related information in the following categories:

- Relations: Relation extensions are used to declare related objects that should be automatically deleted when the parent object is deleted, to indicate the "owning" side of two-sided relations, and to give Kodo JDO more information on field types.

- Schema: You can use schema extensions to dictate column sizes, indexes, and foreign keys.

- Object-Relational Mapping: Using object-relational mapping extensions, you can customize how your object is mapped to the database.

- Miscellaneous: Other extensions, including custom fetch group configuration, caching hints, and sequence information.

All metadata extensions are optional; Kodo JDO will rely on its defaults when no explicit data is provided. If you do choose to specify metadata `<extension>` elements, they must have a `vendor-name` of `kodo`. The next sections present a list of the available extensions in each category.

### 6.2.1. Relation Extensions

One use of relation extensions is to indicate the "owning" side of two-sided relations. Kodo JDO never requires you to use two-sided relations, but doing so allows Kodo to create a more efficient schema by sharing tables and columns between both sides of the relation. For example, consider a hypothetical two-sided relation between the `Company` and `Employee` classes. Each `Employee` object stores a reference to a single `Company` in its `employer` field. Similarly, each `Company` tracks all of its `Employee`s in an `employees` collection.

In this example, there is a logical relationship between the `Employee.employer` and `Company.employees` fields; the relationship is clearly two-sided. In fact, it is what is known as a one-to-many relationship. If we consider how this relationship could be efficiently modelled in the database, we see that each `Employee` record should store the primary key values of its `employer`. Each `Company` record, on the other hand, does not need any reference to its `employees`, because we can model the relation with a simple `SELECT`. To find all employees of company X, we `SELECT` all `Employee` records where the record's `employer` foreign key values matches company X's primary key values.

Because two-sided relations share data structures, Kodo JDO requires you to specify which side of the relation should be used to update the shared structures. This side of the relation is the "owner". In one-to-many relationships like the one between `Company` and `Employee`, the field holding a reference to the single object is always the owner (in this case `Employee.employer`). In other two-sided relations, the choice of which side owns the relation is arbitrary.

Another use of relation extensions is to mark a field as dependent. Objects stored in dependent fields are called dependent objects. Any time a dependent object is removed from its owning field or has its owning object deleted, the dependent object also becomes a candidate for deletion. On flush, Kodo checks whether you have added the dependent object to any other field in the transaction, and if you have not, the unreferenced object is deleted.

The final use of relation extensions is to give Kodo JDO extra information about field types. This is useful when you want your Java code to treat a field as a generic `java.lang.Object` or interface, but you know that the field will actually always hold a relation to another persistent object. Telling Kodo JDO that a generic object or interface field actually stores a persistent relation lets Kodo JDO create a more efficient schema.

#### 6.2.1.1. inverse-owner

Use the `inverse-owner` field extension to indicate that this field is part of a two-sided relation with the named field, and that the named field owns the relation. The named field should not also have this extension; only one field can be the owner. See below for an example.

This extension implies that this field and its inverse owner share a datastructure at the database level. For a purely logical inverse, use `inverse-logical`. T

By default, this extension does not affect runtime behavior. You must still set both sides of the relation manually to keep your object model consistent. You can, however, configure Kodo to manage the relation so that setting one side automatically sets the ohter side as well. See Section 5.3, “Managed Inverses” for details.

#### 6.2.1.2. inverse-logical

The `inverse-logical` field extension marks an inverse relationship which is not shared at the datastore level. This extension is only useful when managed inverses are enabled. Kodo will automatically keep the value of this field and its inverse field in synch. See Section 5.3, “Managed Inverses”.

#### 6.2.1.3. dependent

Setting a value of `true` for the `dependent` field extension indicates that the persistent object stored in this field should be deleted when the parent object is deleted, or when the parent field is nulled.

#### 6.2.1.4. element-dependent

The `element-dependent` field extension is like the the `dependent` extension, but applies to the element values of collection fields. Use this extension for one-to-many or many-to-many relations where the related objects should be deleted along with the owning object.

#### 6.2.1.5. value-dependent

The `value-dependent` field extension is equivalent to the `element-dependent` extension above, but is used for map values rather than collection elements.

#### 6.2.1.6. key-dependent

The `key-dependent` field extension is equivalent to the `value-dependent` extension above, but is used for map keys rather than map values.

#### 6.2.1.7. type

Kodo JDO 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 JDO uses level 1 support. By default, Kodo JDO 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 JDO lumps it together with `java.lang.Object` fields and other non-interface, unrecognized field types, which are all assigned level 3 support.

With the `type` field extension, you can control the level of support given to your unknown/interface-typed fields. Setting the value of this extension to `javax.jdo.spi.PersistenceCapable` -- or just `PersistenceCapable` for short -- indicates that the field value will always be some persistent object, and gives level 2 support. Setting the value of this extension to the full class name 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 `java.lang.Object` -- `Object` for short -- uses level 3 support. This is useful when you have an interface relation that may not hold other persistent objects (recall that Kodo JDO assumes interface fields will always hold persistent instances by default).

#### 6.2.1.8. element-type

The `element-type` field extension is equivalent to the `type` extension above, but is used for the element values of collections with generic/interface `element-type` metadata.

This extension can also be used with externalization (see Section 7.9.22, “Externalization”) to indicate the element type if a field externalizes to a collection.

#### 6.2.1.9. value-type

The `value-type` field extension is equivalent to the `type` extension above, but is used for the values of maps with generic/interface `value-type` metadata.

This extension can also be used with externalization (see Section 7.9.22, “Externalization”) to indicate the value type if a field externalizes to a map.

#### 6.2.1.10. key-type

The `key-type` field extension is equivalent to the `type` extension above, but is used for the keys of maps with generic/interface `key-type` metadata.

This extension can also be used with externalization (see Section 7.9.22, “Externalization”) to indicate the key type if a field externalizes to a map.

#### 6.2.1.11. lrs

Use this boolean field-level extension to mark fields that should use Kodo's special large result set collection or map proxies. A complete description of large result set proxies is available in Section 5.4.3.2, “Large Result Set Proxies”.

#### 6.2.1.12. Example

    <jdo>
      <package name="com.xyz">
        <class name="Company">
          <field name="employees">
            <collection element-type="Employee"/>
            <!-- specify the field that owns this two-sided relation -->
            <extension vendor-name="kodo" key="inverse-owner" value="employer"/>
            <!-- delete all employees when the company is deleted    -->
            <extension vendor-name="kodo" key="element-dependent" value="true"/>
            <!-- very large company, thousands of employees          -->
            <extension vendor-name="kodo" key="lrs" value="true"/>
          </field>
        </class>
        <class name="Employee">
          <field name="employer">
            <!-- no inverse-owner on this field, because it is the owner -->
          </field>
        </class>
      </package>
    </jdo>

### 6.2.2. Schema Extensions

If you use Kodo JDO's automatic schema creation and migration through the mapping tool, you may want to exercise some control over nuances like column sizes, indexes, and foreign keys. Kodo JDO provides a simple set of metadata extensions you can use to optimize the schema generated for your classes. None of these extensions are used at runtime, or if you have an existing schema. They are only used when the mapping tool generates the schema for the classes the first time it runs on them.

#### 6.2.2.1. jdbc-size

The `jdbc-size` field extension sets the size of the column used to hold the field's data. If this extension is not given, string fields default to a column size of 255, and other types use the database default. Use a value of -1 to indicate that this field is of an unlimited size (this typically translates to using a `BLOB` or `CLOB` mapping for the field).

#### 6.2.2.2. jdbc-element-size

The `jdbc-element-size` field extension is equivalent to the `jdbc-size` extension, but applies to the data stored in each element of a collection or array. Note that if the size is set such that Kodo JDO would use a `BLOB` mapping for each element, the entire collection will be collapsed into a single `BLOB` value instead for efficiency.

#### 6.2.2.3. jdbc-value-size

The `jdbc-value-size` field extension is equivalent to the `jdbc-element-size` extension, but applies to map values rather than collection elements.

#### 6.2.2.4. jdbc-key-size

The `jdbc-key-size` field extension is equivalent to the `jdbc-value-size` extension, but applies to map keys rather than values.

#### 6.2.2.5. jdbc-indexed

The `jdbc-indexed` field extension specifies whether the column holding the data for this field should be indexed. Recognized values are `true`, `false`, and `unique`. By default, Kodo JDO does not index columns unless they hold a primary key value for a related database record (i.e. unless they are part of a foreign key, actual or logical).

#### 6.2.2.6. jdbc-element-indexed

The `jdbc-element-indexed` field extension is equivalent to the `jdbc-indexed` extension, but applies to columns holding collection elements.

#### 6.2.2.7. jdbc-value-indexed

The `jdbc-value-indexed` field extension is equivalent to the `jdbc-element-indexed` extension, but applies to map values rather than collection elements.

#### 6.2.2.8. jdbc-key-indexed

The `jdbc-key-indexed` field extension is equivalent to the `jdbc-value-indexed` extension, but applies to map keys rather than values.

#### 6.2.2.9. jdbc-ref-indexed

The `jdbc-ref-indexed` field indexing extension applies to the back-reference columns of a mapping. When the data for a mapping is in a row other than the row that holds the owning object's primary key values (a.k.a. the primary row), the back-reference columns act as a foreign key back to the primary row.

For example, map fields are typically stored in a table by themselves. The table consists of column(s) for the map key, column(s) for the map value, and back-reference column(s) that hold the owning object's primary key values, and which can be used to join back to the owning object's primary row.

Kodo JDO indexes all back reference columns by default, because they are often used in joins.

#### 6.2.2.10. jdbc-version-ind-indexed

The `jdbc-version-ind-indexed` class extension is equivalent to the `jdbc-indexed` extension, but applies to the columns of the class' version indicator. Defaults to `true`.

#### 6.2.2.11. jdbc-class-ind-indexed

The `jdbc-class-ind-indexed` class extension is equivalent to the `jdbc-indexed` extension, but applies to the columns of the class' class indicator. Defaults to `true`.

#### 6.2.2.12. jdbc-delete-action

If a field holds a relation to another object, you can use the `jdbc-delete-action` field extension to control the delete action of the database foreign key that models this relation. Possible values are:

- `exception`: Do not allow the related record to be deleted until this record has been deleted.

- `exception-deferred`: Equivalent to the `exception` action, but the constraint is not evaluated until the database transaction is committed.

- `null`: Null the column(s) of this foreign key when the related record is deleted.

- `null-deferred`: Equivalent to the `null` action, but the constraint is not evaluated until the database transaction is committed.

- `default`: Set the column(s) of this foreign key to their database default values when the related record is deleted.

- `default-deferred`: Equivalent to the `default` action, but the constraint is not evaluated until the database transaction is committed.

- `cascade`: Delete this record when the related record is deleted.

- `cascade-deferred`: Equivalent to the `cascade` action, but the constraint is not evaluated until the database transaction is committed.

- `none`: Do not perform any action when the related record is deleted.

Kodo JDO defaults all relations to the `none` delete action, meaning the foreign key is only logical, and does not exist in the database. If you choose to use the `exception` action, and you choose not to use deferred foreign keys, make sure to enable Kodo JDO's statement ordering option to meet foreign key dependencies. Statement ordering is covered in Section 4.11, “SQL Statement Ordering & Foreign Keys”.

Note that not all databases support all delete actions. If you specify an action that is not supported, the relevant foreign key will not be created. This will not have an adverse effect on Kodo JDO's runtime behavior.

Note that this extension only controls what Kodo expects the database server to do when a row is deleted: Kodo will not itself delete the foreign rows, but merely knows to expect them to be deleted. To have Kodo perform these actions (e.g., to have automatic client-side cascading delete), you should instead use the "dependent" extensions. See Section 6.2.1.3, “dependent”.

#### 6.2.2.13. jdbc-element-delete-action

The `jdbc-element-delete-action` field extension is equivalent to the `jdbc-delete-action` extension, but applies to collections that store related objects in each element.

#### 6.2.2.14. jdbc-value-delete-action

The `jdbc-value-delete-action` field extension is equivalent to the `jdbc-element-delete-action` extension, but applies to maps that store related objects in each value.

#### 6.2.2.15. jdbc-key-delete-action

The `jdbc-key-delete-action` field extension is equivalent to the `jdbc-value-delete-action` extension, but applies to maps that store related objects in each key.

#### 6.2.2.16. jdbc-ref-delete-action

The `jdbc-ref-delete-action` field extension is equivalent to the `jdbc-delete-action` extension, but applies to the back-reference columns of a mapping. See the `jdbc-ref-indexed` description above for a discussion of back-reference columns.

If you are defining metadata for a subclass that lies in a separate table than the parent class, you can use this extension as a class-level extension control the delete action of the foreign key linking the child table records to the parent table records.

#### 6.2.2.17. Example

    <jdo>
      <package name="com.xyz">
        <class name="Company">
          <field name="commonName">
            <!-- index the company name because we search on it    -->
            <extension vendor-name="kodo" key="jdbc-indexed" value="true"/>
          </field>
          <field name="description">
            <!-- this string should be unlimited length (clob)     -->
            <extension vendor-name="kodo" key="jdbc-size" value="-1"/>
          </field>
          <field name="offices">
            <collection element-type="Address"/>
            <!-- remove the row in the offices xref table when the -->
            <!-- address it refers to is deleted                   -->
            <extension vendor-name="kodo" key="jdbc-element-delete-action" value="cascade"/>
          </field>
        </class>
      </package>
    </jdo>

### 6.2.3. Object-Relational Mapping Extensions

Object-relational mapping is discussed in detail in Chapter 7, Object-Relational Mapping. This section only reviews extensions that give hints to the mapping tool (see Section 7.1, “Mapping Tool”) about how to map your persistent classes and their fields, just as the schema extensions we reviewed above provide hints on how to create the schema. Most users can ignore these extensions, because they will be satisfied with Kodo JDO's defaults, or because they will explicitly specify all mapping data themselves as described in Chapter 7, Object-Relational Mapping. The extensions listed here are for intermediate users who want Kodo JDO to handle most of the mapping process, but have a few special needs. Note that the `jdbc-*-name` extensions below are not used at runtime, or if you have mappings already made for the relevant classes and fields. They are only used by the mapping tool when deciding how to map your objects the first time it is run on them.

#### 6.2.3.1. jdbc-class-map-name

`jdbc-class-map-name`: This class extension specifies the type of class mapping to use for the class. The value of the extension can be either the short mapping type name, such as `flat`, `vertical`, or `horizontal`, or the full class name of the `ClassMapping` class to install. Using the full class name also allows you to specify custom class mappings that are not built in to Kodo JDO. See Section 7.6, “Class Mapping” for details on the built-in class mappings that are available.

When mapping a persistent subclass, the value of this extension overrides the `kodo.jdbc.SubclassMapping` configuration property.

Set this extension to `none` for classes that do not need mappings because they will never never be used as persistent objects, or because they will always be used in embedded persistent fields.

#### 6.2.3.2. jdbc-version-ind-name

The `jdbc-version-ind-name` class extension specifies the type of version indicator to use for the class. Version indicators can only be specified for base classes. The value of the extension can be either the short mapping type name, such as `version-number` or `state-image`, or the full class name of the `VersionIndicator` class to install. Using the full class name also allows you to specify custom indicators that are not built in to Kodo JDO.

The value of this extension overrides the `kodo.jdbc.VersionIndicator` configuration property.

Specify a value of `none` to forgo a version indicator on the class. Note that when you do not use a version indicator, optimistic lock exceptions cannot be detected.

#### 6.2.3.3. jdbc-class-ind-name

The `jdbc-class-ind-name` class extension specifies the type of class indicator (See Section 7.8, “Class Indicator”) to use for the class. Class indicators can only be specified for base classes. The value of the extension can be either the short mapping type name, such as `in-class-name`, or the full class name of the `ClassIndicator` class to install. Using the full class name also allows you to specify custom indicators that are not built in to Kodo JDO.

The value of this extension overrides the `kodo.jdbc.ClassIndicator` configuration property.

Specify a value of `none` to forgo a class indicator on the class. Note that when you do not use a class indicator, you cannot inherit from this class with other persistent classes.

#### 6.2.3.4. jdbc-field-map-name

The `jdbc-field-map-name` field extension specifies the type of field mapping to use for the field. The value of the extension can be either the short mapping type name, such as `value` or `one-one`, or the full class name of the `FieldMapping` class to install. Using the full class name also allows you to specify custom field mappings that are not built in to Kodo JDO. Use a value of `none` for all fields in classes that have a `none` class mapping.

#### 6.2.3.5. jdbc-ordered

The `jdbc-ordered` field extension specifies whether special care should be taken to keep the elements of this collection field ordered when they are retrieved from the database. Typically, databases do not maintain ordering. Setting this extension to `true` will add a special ordering column to the table holding the collection elements. Kodo JDO can then use this ordering column to retrieve the collection elements in the same order they appeared in memory when they were last flushed.

This extension defaults to `true` for array and `java.util.List` fields, and `false` for all other collection types.

Only the owning side of a two-sided many-many relation can maintain collection order.

#### 6.2.3.6. jdbc-container-meta

Container metadata is used to record non-essential information about collection and map fields. If this extension is set to `true`, collections and maps will be able to distinguish between the empty state and the null state. If this extension is set to `false` or is unset, then it will not be possible for Kodo to differentiate between these two states. In this situation, all collections and maps in persistent objects loaded from the database will be non-null.

#### 6.2.3.7. jdbc-null-ind

The `jdbc-null-ind` field extension is used only for embedded one-to-one mappings. Set the value of this extension to the name of the field in the embedded class that can be used to tell whether the embedded object is null. When loading an embedded object from the database, the system will check the column(s) for this field to see if they are null. If so, it will assume the embedded object was null when stored, and will assign null to the embedding field. Otherwise, it will instantiate an instance of the embedded class and assign the new instance to the embedding field.

The value of this extension defaults to `synthetic`, which means the system will create a special column in the embedding class' table just to hold whether or not the embedded object is null. In this configuration the system does not rely on the value of any embedded class field.

#### 6.2.3.8. externalizer

The `externalizer` field extension names a method to transform a field value that is unsupported by JDO to one that is supported. See Section 7.9.22, “Externalization” for details.

#### 6.2.3.9. factory

The `factory` field extension names a method to re-create a field value from its externalized form. See Section 7.9.22, “Externalization” for details.

#### 6.2.3.10. external-values

The `external-values` field extension declares values for transformation of simple fields to different constant values in the datastore. See Section 7.9.23, “External Values” for details.

#### 6.2.3.11. jdbc-class-ind-value

The `jdbc-class-ind-value` class extension is reserved for classes that use the metadata value class indicator (see Section 7.8.2, “Metadata Value Indicator”). This indicator requires that all classes use this extension to specify the database value that indicates a record of the owning class. See the class indicator description for details.

#### 6.2.3.12. Example

    <jdo>
      <package name="com.xyz">
        <class name="Company">
          <!-- we don't need to ever inherit from this type        -->
          <extension vendor-name="kodo" key="jdbc-class-ind-name" value="none"/>
          <field name="offices">
            <collection element-type="Address"/>
            <!-- keep this collection ordered                      -->
            <extension vendor-name="kodo" key="jdbc-ordered" value="true"/>
          </field>
        </class>
        <class name="Employee" persistence-capable-superclass="Person">
          <!-- use a vertical class mapping for this subclass      -->
          <extension vendor-name="kodo" key="jdbc-class-map-name" value="vertical"/>
          <field name="male">
            <!-- use a custom mapping that maps this boolean to an -->
            <!-- 'M' or 'F' value in the database                  -->
            <extension vendor-name="kodo" key="jdbc-field-map-name"
              value="com.xyz.BooleanToCharMapping"/>
          </field>
        </class>
      </package>
    </jdo>

### 6.2.4. Miscellaneous Extensions

Kodo JDO recognizes the following miscellaneous extensions.

#### 6.2.4.1. fetch-group

The `fetch-group` field extension names a custom fetch group for the field. We discuss custom fetch groups in Section 14.5, “Fetch Groups”.

#### 6.2.4.2. lock-group

The `lock-group` field extension names the lock group for the field, allowing fine-grained optimistic locking concurrency. We discuss lock groups in Section 14.6, “Lock Groups”.

#### 6.2.4.3. data-cache

The `data-cache` class extension specifies data cache for this class. It can be one of the following values:

- `true`: this class should be cached in the default cache, as configured by the `kodo.DataCache` configuration parameter. This is the default value.

- `false`: this class should not be cached.

- `cache-name`: this class should be cached in the named cache called cache-name.

If not specified and if caching is enabled, members of the class will be stored in the default data cache.

#### 6.2.4.4. data-cache-timeout

While the `kodo.DataCacheTimeout` configuration property sets the number of milliseconds that data in the data cache remains valid on a system-wide basis, the `data-cache-timeout` class extension overrides the system setting for an individual class. Use a value of -1 for no expiration. This is the default value.

#### 6.2.4.5. subclass-fetch-mode

This class-level extension determines how Kodo will select data in subclass tables. Legal values are `none`, `join`, and `parallel`. See Section 14.2, “Eager Fetching” for a discussion of each fetch mode.

#### 6.2.4.6. eager-fetch-mode

This field-level extension states the field's preference for how it is eagerly loaded. Note that turning on and off eager fetching for fields is a fetch group and runtime operation; this extension only declares what type of eager fetching to use if this field is eager fetched. Furthermore, this extension is only applicable to fields that represent relations or collections.

A value of `none` ensures that this field will never be eagerly fetched. It will always load in its own independent select. A value of `join` means to use a join to read this field along with the parent object data. This is the default for direct relations. For collection fields, the default is `parallel`. Parallel mode uses separate selects executed in parallel for each eager collection. Section 14.2, “Eager Fetching” discusses each fetch mode in more detail, and describes when eager fetching takes effect.

#### 6.2.4.7. jdbc-sequence-factory

The `jdbc-sequence-factory` class extension specifies a plugin string describing the `SequenceFactory` to use to generate unique datastore identity values for new instances of this class. If not given, the class will use the default sequence factory defined in the `kodo.jdbc.SequenceFactory` configuration property (see Section 2.6.55, “kodo.jdbc.SequenceFactory”). For more information on sequence factories, see Section 5.2.3.1, “Sequence Factory”.

#### 6.2.4.8. jdbc-sequence-name

When using the `ClassSequenceFactory`, the `jdbc-sequence-name` class extension contains the name of the database sequence for the class. If not given, the default sequence will be used.

#### 6.2.4.9. jdbc-auto-increment

Placing this extension beneath a `<class>` element tells Kodo that its datastore identity primary key column is auto-incrementing. Placing it beneath a `<field>` element indicates that the field uses an auto-increment column. If you are using auto-increment columns, then you must specify this extension in the right places, because Kodo cannot reliably determine which columns are auto-incrementing through the JDBC driver alone. Please be sure to read Section 5.2.3.2, “Auto-Increment” for additional steps you must take to use auto-incrementing primary key columns.

#### 6.2.4.10. Example

    <jdo>
      <package name="com.xyz">
        <class name="Company">
          <extension vendor-name="kodo" key="data-cache" value="false"/>
          <extension vendor-name="kodo" key="jdbc-sequence-name" value="COMP"/>
        </class>
        <class name="Person">
          <extension vendor-name="kodo" key="jdbc-auto-increment" value="true"/>
        </class>
        <class name="Form" objectid-class="FormId">
          <field name="id" primary-key="true">
            <extension vendor-name="kodo" key="jdbc-auto-increment" value="true"/>
          </field>
        </class>
      </package>
    </jdo>

Prev | Up | Next
Chapter 6. Metadata | Home | Chapter 7. Object-Relational Mapping