blob: 987ee3a947ca299bcf68b5a1b0721fe08f169b58 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<chapter id="ref_guide_meta">
<title>
Metadata
</title>
<para>
The JPA Overview covers JPA metadata in <xref linkend="jpa_overview_meta"/>.
This chapter discusses OpenJPA's extensions to standard JPA metadata.
</para>
<section id="ref_guide_meta_factory">
<title>
Metadata Factory
</title>
<indexterm zone="ref_guide_meta_factory">
<primary>
metadata
</primary>
<secondary>
loading and storing
</secondary>
<see>
MetaDataFactory
</see>
</indexterm>
<para>
The <link linkend="openjpa.MetaDataFactory"><literal>openjpa.MetaDataFactory
</literal></link> configuration property controls metadata loading and storing.
This property takes a plugin string (see
<xref linkend="ref_guide_conf_plugins"/>) describing a concrete
<ulink url="../javadoc/org/apache/openjpa/meta/MetaDataFactory.html">
<classname>org.apache.openjpa.meta.MetaDataFactory</classname></ulink>
implementation. A metadata factory can load mapping information as well as
persistence metadata, or it can leave mapping information to a separate
<emphasis>mapping factory</emphasis> (see
<xref linkend="ref_guide_mapping_factory"/>). OpenJPA recognizes the
following built-in metadata factories:
</para>
<itemizedlist>
<listitem>
<para>
<literal>jpa</literal>: Standard JPA metadata. This is an alias for the
<ulink url="../javadoc/org/apache/openjpa/persistence/PersistenceMetaDataFactory.html">
<classname>
org.apache.openjpa.persistence.PersistenceMetaDataFactory</classname></ulink>.
</para>
</listitem>
</itemizedlist>
<para>
JPA has built-in settings for listing your persistent classes, which
the <link linkend="jpa_overview_persistence_xml">JPA Overview</link> describes.
OpenJPA supports these JPA standard settings by translating them into its own
internal metadata factory properties. Each internal property represents a
different mechanism for locating persistent types; you can choose the mechanism
or combination of mechanisms that are most convenient. See
<xref linkend="ref_guide_pc_pcclasses"/> for a discussion of when it is
necessary to list your persistent classes.
</para>
<itemizedlist>
<listitem>
<para>
<literal>Types</literal>: A semicolon-separated list of fully-qualified
persistent class names.
</para>
</listitem>
<listitem>
<para>
<literal>Resources</literal>: A semicolon-separated list of resource paths to
metadata files or jar archives. Each jar archive will be scanned for
annotated JPA entities.
</para>
</listitem>
<listitem>
<para>
<literal>URLs</literal>: A semicolon-separated list of URLs of metadata files
or jar archives. Each jar archive will be scanned for annotated JPA
entities.
</para>
</listitem>
<listitem>
<para>
<literal>ClasspathScan</literal>: A semicolon-separated list of directories or
jar archives listed in your classpath. Each directory and jar archive will be
scanned for annotated JPA entities.
</para>
</listitem>
</itemizedlist>
<example id="ref_guide_meta_stdfactoryex">
<title>
Setting a Standard Metadata Factory
</title>
<programlisting>
&lt;property name="openjpa.MetaDataFactory" value="jpa(ClasspathScan=build;lib.jar)"/&gt;
</programlisting>
</example>
<example id="ref_guide_meta_customfactoryex">
<title>
Setting a Custom Metadata Factory
</title>
<programlisting>
&lt;property name="openjpa.MetaDataFactory" value="com.xyz.CustomMetaDataFactory"/&gt;
</programlisting>
</example>
</section>
<!-- start added -->
<section id="ref_guide_meta_repository">
<para>The openjpa.MetaDataRepository configuration property controls the configuration of
the MetaDataRepository. The following are valid properties:</para>
<itemizedlist>
<listitem><para>
<literal>Preload</literal>: A boolean property. If true, OpenJPA will eagerly load the repository on
EntityManagerFactory creation. As a result, all Entity classes will be eagerly loaded by the JVM.
Once MetaData preloading completes, all locking is removed from the MetaDataRepository and this will
result in a much more scalable repository. If false, the repository will be lazily loaded as Entity
classes are loaded by the JVM. The default value is false.
</para>
</listitem>
</itemizedlist>
<title>Metadata Repository</title>
<example id="ref_guide_meta_repo">
<title>
Setting the Preload Property on Metadata Repository
</title>
<programlisting>
&lt;property name="openjpa.MetaDataRepository" value="Preload=true"/&gt;
</programlisting>
</example>
</section>
<!-- end added -->
<section id="ref_guide_meta_jpa">
<title>
Additional JPA Metadata
</title>
<indexterm zone="ref_guide_meta_jpa">
<primary>
metadata
</primary>
<secondary>
JPA additions
</secondary>
</indexterm>
<para>
This section describes OpenJPA's core additions to standard entity metadata. We
present the object-relational mapping syntax to support these additions in
<xref linkend="ref_guide_mapping_jpa"/>. Finally,
<xref linkend="ref_guide_meta_ext"/> covers additional extensions to JPA
metadata that allow you to access auxiliary OpenJPA features.
</para>
<section id="ref_guide_meta_jpa_datastoreid">
<title>
Datastore Identity
</title>
<indexterm zone="ref_guide_meta_jpa_datastoreid">
<primary>
identity
</primary>
<secondary>
datastore
</secondary>
</indexterm>
<para>
JPA typically requires you to declare one or more <literal>Id</literal> fields
to act as primary keys. OpenJPA, however, can create and maintain a surrogate
primary key value when you do not declare any <literal>Id</literal> fields. This
form of persistent identity is called <emphasis>datastore identity</emphasis>.
<xref linkend="ref_guide_pc_oid"/> discusses OpenJPA's support for
datastore identity in JPA. We cover how to map your datastore identity primary
key column in <xref linkend="ref_guide_mapping_jpa_datastoreid"/>
</para>
</section>
<section id="ref_guide_meta_jpa_version">
<title>
Surrogate Version
</title>
<indexterm zone="ref_guide_meta_jpa_version">
<primary>
version
</primary>
<secondary>
surrogate
</secondary>
</indexterm>
<para>
Just as OpenJPA can maintain your entity's identity without any <literal>Id
</literal> fields, OpenJPA can maintain your entity's optimistic version without
any <literal>Version</literal> fields.
<xref linkend="ref_guide_mapping_jpa_version"/> shows you how to map
surrogate version columns.
</para>
</section>
<section id="ref_guide_meta_jpa_persistent">
<title>
Persistent Field Values
</title>
<indexterm zone="ref_guide_meta_jpa_persistent">
<primary>
persistent fields
</primary>
</indexterm>
<para>
JPA defines <literal>Basic</literal>, <literal>Lob</literal>, <literal>Embedded
</literal>, <literal>ManyToOne</literal>, and <literal>OneToOne</literal>
persistence strategies for direct field values. OpenJPA supports all of these
standard strategies, but adds one of its own: <literal>Persistent</literal>.
The <ulink url="../javadoc/org/apache/openjpa/persistence/Persistent.html">
<classname>org.apache.openjpa.persistence.Persistent</classname></ulink>
metadata annotation can represent any direct field value, including custom
types. It has the following properties:
</para>
<itemizedlist>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the field eagerly or
lazily. Corresponds exactly to the same-named property of standard JPA
annotations such as <link linkend="jpa_overview_meta_basic"><classname> Basic
</classname></link>. Defaults to <literal>FetchType.EAGER</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>CascadeType[] cascade</literal>: Array of enum values defining cascade
behavior for this field. Corresponds exactly to the same-named property of
standard JPA annotations such as <link linkend="jpa_overview_meta_manytoone">
<classname> ManyToOne</classname></link>. Defaults to empty array.
</para>
</listitem>
<listitem>
<para>
<literal>String mappedBy</literal>: Names the field in the related entity that
maps this bidirectional relation. Corresponds to the same-named property of
standard JPA annotations such as <link linkend="jpa_overview_meta_onetoone">
<classname> OneToOne</classname></link>.
</para>
</listitem>
<listitem>
<para>
<literal>boolean optional</literal>: Whether the value can be null. Corresponds
to the same-named property of standard JPA annotations such as
<link linkend="jpa_overview_meta_manytoone"><classname> ManyToOne</classname>
</link>, but can apply to non-entity object values as well. Defaults to
<literal>true</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>boolean embedded</literal>: Set this property to <literal>true
</literal> if the field value is stored as an embedded object.
</para>
</listitem>
</itemizedlist>
<para>
Though you can use the <classname>Persistent</classname> annotation in place of
most of the standard direct field annotations mentioned above, we recommend
primarily using it for non-standard and custom types for which no standard JPA
annotation exists. For example, <xref linkend="ref_guide_mapping_jpa_columns"/>
demonstrates the use of the <classname>Persistent</classname> annotation
to denote a persistent <classname>java.awt.Point</classname> field.
</para>
</section>
<section id="ref_guide_meta_jpa_persistent_coll">
<title>Persistent Collection Fields</title>
<indexterm zone="ref_guide_meta_jpa_persistent_coll">
<primary>persistent fields</primary>
<secondary>collection metadata</secondary>
</indexterm>
<para>
JPA standardizes support for collections of entities with the <literal>
OneToMany</literal> and <literal>ManyToMany</literal> persistence strategies.
OpenJPA supports these strategies, and may be extended for other strategies as
well. For extended strategies, use the
<ulink url="../javadoc/org/apache/openjpa/persistence/PersistentCollection.html">
<classname>org.apache.openjpa.persistence.PersistentCollection</classname></ulink> metadata
annotation to represents any persistent collection field. It has the following
properties:
</para>
<itemizedlist>
<listitem>
<para>
<literal>Class elementType</literal>: The class of the collection elements.
This information is usually taken from the parameterized collection element
type. You must supply it explicitly, however, if your field isn't a
parameterized type.
</para>
</listitem>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the collection eagerly or
lazily. Corresponds exactly to the same-named property of standard JPA
annotations such as <link linkend="jpa_overview_meta_basic"><classname>
Basic</classname></link>. Defaults to <literal>FetchType.LAZY</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>String mappedBy</literal>: Names the field in the related entity that
maps this bidirectional relation. Corresponds to the same-named property of
standard JPA annotations such as <link linkend="jpa_overview_meta_manytomany">
<classname>ManyToMany</classname></link>.
</para>
</listitem>
<listitem>
<para>
<literal>CascadeType[] elementCascade</literal>: Array of enum values defining
cascade behavior for the collection elements. Corresponds exactly to the
<literal>cascade</literal> property of standard JPA annotations such as
<link linkend="jpa_overview_meta_manytomany"><classname>
ManyToMany</classname></link>. Defaults to empty array.
</para>
</listitem>
<listitem>
<para>
<literal>boolean elementEmbedded</literal>: Set this property to <literal>true
</literal> if the elements are stored as embedded objects.
</para>
</listitem>
</itemizedlist>
</section>
<section id="ref_guide_meta_jpa_persistent_map">
<title>Persistent Map Fields</title>
<indexterm zone="ref_guide_meta_jpa_persistent_map">
<primary>persistent fields</primary>
<secondary>map metadata</secondary>
</indexterm>
<para>
JPA has limited support for maps. If you extend JPA's standard map support to
encompass new mappings, use the
<ulink url="../javadoc/org/apache/openjpa/persistence/PersistentMap.html">
<classname>org.apache.openjpa.persistence.PersistentMap</classname></ulink> metadata
annotation to represent your custom persistent map fields. It has the
following properties:
</para>
<itemizedlist>
<listitem>
<para>
<literal>Class keyType</literal>: The class of the map keys. This information
is usually taken from the parameterized map key type. You must supply it
explicitly, however, if your field isn't a parameterized type.
</para>
</listitem>
<listitem>
<para>
<literal>Class elementType</literal>: The class of the map values. This
information is usually taken from the parameterized map value type. You must
supply it explicitly, however, if your field isn't a parameterized type.
</para>
</listitem>
<listitem>
<para>
<literal>FetchType fetch</literal>: Whether to load the collection eagerly or
lazily. Corresponds exactly to the same-named property of standard JPA
annotations such as <link linkend="jpa_overview_meta_basic"><classname>
Basic</classname></link>. Defaults to <literal>FetchType.LAZY</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>CascadeType[] keyCascade</literal>: Array of enum values defining
cascade behavior for the map keys. Corresponds exactly to the <literal>cascade
</literal> property of standard JPA annotations such as
<link linkend="jpa_overview_meta_manytoone"><classname>
ManyToOne</classname></link>. Defaults to empty array.
</para>
</listitem>
<listitem>
<para>
<literal>CascadeType[] elementCascade</literal>: Array of enum values defining
cascade behavior for the map values. Corresponds exactly to the
<literal>cascade</literal> property of standard JPA annotations such as
<link linkend="jpa_overview_meta_manytoone"><classname>
ManyToOne</classname></link>. Defaults to empty array.
</para>
</listitem>
<listitem>
<para>
<literal>boolean keyEmbedded</literal>: Set this property to <literal>true
</literal> if the map keys are stored as embedded objects.
</para>
</listitem>
<listitem>
<para>
<literal>boolean elementEmbedded</literal>: Set this property to <literal>
true</literal> if the map values are stored as embedded objects.
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="ref_guide_meta_ext">
<title>
Metadata Extensions
</title>
<indexterm zone="ref_guide_meta_ext">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
</indexterm>
<para>
OpenJPA extends standard metadata to allow you to access advanced OpenJPA
functionality. This section covers persistence metadata extensions; we discuss
mapping metadata extensions in <xref linkend="ref_guide_mapping_ext"/>.
All metadata extensions are optional; OpenJPA will rely on its defaults when no
explicit data is provided.
</para>
<section id="ref_guide_meta_class">
<title>
Class Extensions
</title>
<para>
OpenJPA recognizes the following class extensions:
</para>
<section id="fetch-groups">
<title>
Fetch Groups
</title>
<indexterm zone="fetch-groups">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
fetch groups
</tertiary>
<seealso>
fetch groups
</seealso>
</indexterm>
<para>
The <ulink url="../javadoc/org/apache/openjpa/persistence/FetchGroups.html">
<classname>org.apache.openjpa.persistence.FetchGroups</classname></ulink> and
<ulink url="../javadoc/org/apache/openjpa/persistence/FetchGroup.html">
<classname>org.apache.openjpa.persistence.FetchGroup</classname></ulink>
annotations allow you to define fetch groups in your JPA entities.
<xref linkend="ref_guide_fetch"/> discusses OpenJPA's support for fetch
groups in general; see <xref linkend="ref_guide_fetch_custom"/> for how to
use these annotations in particular.
</para>
</section>
<section id="data-cache">
<title>
Data Cache
</title>
<indexterm zone="data-cache">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
data cache
</tertiary>
<seealso>
caching
</seealso>
</indexterm>
<para>
<xref linkend="ref_guide_cache"/> examines caching in OpenJPA. Metadata
extensions allow individual classes to override system caching defaults.
</para>
<para>
OpenJPA defines the
<ulink url="../javadoc/org/apache/openjpa/persistence/DataCache.html">
<classname>org.apache.openjpa.persistence.DataCache</classname></ulink>
annotation for caching information. This annotation has the following
properties:
</para>
<itemizedlist>
<listitem>
<para>
<literal>boolean enabled</literal>: Whether to cache data for instances of the
class. Defaults to <literal>true</literal> for base classes, or the superclass
value for subclasses. If you set this property to <literal>false</literal>, all
other properties are ignored.
</para>
</listitem>
<listitem>
<para>
<literal>int timeout</literal>: The number of milliseconds data for the class
remains valid. Use -1 for no timeout. Defaults to the
<link linkend="openjpa.DataCacheTimeout"><literal> openjpa.DataCacheTimeout
</literal></link> property value.
</para>
</listitem>
</itemizedlist>
</section>
<section id="detached-state-field">
<title>
Detached State
</title>
<indexterm zone="detached-state-field">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
detached state field
</tertiary>
<seealso>
detachment
</seealso>
</indexterm>
<para>
The OpenJPA <link linkend="ref_guide_pc_enhance">enhancer</link> may add a
synthetic field to detachable classes to hold detached state (see
<xref linkend="ref_guide_detach_graph"/> for details). You can instead
declare your own detached state field or suppress the creation of a detached
state field altogether. In the latter case, your class must not use
<link linkend="ref_guide_pc_oid">datastore identity</link>, and should declare
a version field to detect optimistic concurrency errors during detached
modifications.
</para>
<para>
OpenJPA defines the
<ulink url="../javadoc/org/apache/openjpa/persistence/DetachedState.html">
<classname>org.apache.openjpa.persistence.DetachedState</classname></ulink>
annotation for controlling detached state. When used to annotate a class,
<classname>DetachedState</classname> recognizes the following properties:
</para>
<itemizedlist>
<listitem>
<para>
<literal>boolean enabled</literal>: Set to false to suppress the use of
detached state.
</para>
</listitem>
<listitem>
<para>
<literal>String fieldName</literal>: Use this property to declare your own
detached state field. The field must be of type <classname>Object</classname>.
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.
</para>
</listitem>
</itemizedlist>
<para>
If you declare your own detached state field, you can annotate that field with
<classname>DetachedState</classname> directly, rather than placing the
annotation at the class level and using the <literal>fieldName</literal>
property. When placed on a field, <classname>DetachedState</classname> acts as a
marker annotation; it does not recognize any properties. Your annotated field
must be of type <classname>Object</classname>.
</para>
</section>
</section>
<section id="ref_guide_meta_field">
<title>
Field Extensions
</title>
<para>
OpenJPA recognizes the following field extensions:
</para>
<section id="dependent">
<title>
Dependent
</title>
<indexterm zone="dependent">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
dependent
</tertiary>
</indexterm>
<para>
In a <emphasis>dependent</emphasis> 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 <literal>
Magazine.coverArticle</literal> field is marked dependent, then setting
<literal>Magazine.coverArticle</literal> to a new <classname>Article</classname>
instance will automatically delete the old <classname>Article</classname> stored
in the field. Similarly, deleting a <classname>Magazine</classname> object will
automatically delete its current cover <classname>Article</classname>. (This
latter processing is analogous to using JPA's CascadeType.REMOVE functionality
as described in <xref linkend="jpa_overview_meta_cascade"/>.) You can
prevent an orphaned dependent object from being automatically deleted by
assigning it to another relation in the same transaction.
</para>
<para>
OpenJPA offers a family of marker annotations to denote dependent relations in
JPA entities:
</para>
<itemizedlist>
<listitem>
<para>
<ulink url="../javadoc/org/apache/openjpa/persistence/Dependent.html">
<classname> org.apache.openjpa.persistence.Dependent</classname></ulink>: Marks
a direct relation as dependent.
</para>
</listitem>
<listitem>
<para>
<ulink url="../javadoc/org/apache/openjpa/persistence/ElementDependent.html">
<classname> org.apache.openjpa.persistence.ElementDependent</classname></ulink>
: Marks the entity elements of a collection, array, or map field as dependent.
</para>
</listitem>
<listitem>
<para>
<ulink url="../javadoc/org/apache/openjpa/persistence/KeyDependent.html">
<classname> org.apache.openjpa.persistence.KeyDependent</classname></ulink>:
Marks the key entities in a map field as dependent.
</para>
</listitem>
</itemizedlist>
</section>
<section id="load-fetch-group">
<title>
Load Fetch Group
</title>
<indexterm zone="load-fetch-group">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
load fetch group
</tertiary>
</indexterm>
<indexterm zone="load-fetch-group">
<primary>
fetch groups
</primary>
<secondary>
load fetch group
</secondary>
</indexterm>
<para>
The <ulink url="../javadoc/org/apache/openjpa/persistence/LoadFetchGroup.html">
<classname>org.apache.openjpa.persistence.LoadFetchGroup</classname></ulink>
annotation specifies a field's load fetch group.
<xref linkend="ref_guide_fetch"/> discusses OpenJPA's support for fetch groups
in general; see <xref linkend="ref_guide_fetch_custom"/> for how to use this
annotation in particular.
</para>
</section>
<section id="lrs">
<title>
LRS
</title>
<indexterm zone="lrs">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
lrs
</tertiary>
<seealso>
large result sets
</seealso>
</indexterm>
<para>
This boolean extension, denoted by the OpenJPA
<ulink url="../javadoc/org/apache/openjpa/persistence/LRS.html"><classname>
org.apache.openjpa.persistence.LRS</classname></ulink> annotation,
indicates that a field should use OpenJPA's special large result set collection
or map proxies. A complete description of large result set proxies is available
in <xref linkend="ref_guide_pc_scos_proxy_lrs"/>.
</para>
</section>
<section id="inverse-logical">
<title>
Inverse-Logical
</title>
<indexterm zone="inverse-logical">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
inverse-logical
</tertiary>
<seealso>
bidirectional relations
</seealso>
</indexterm>
<para>
This extension names the inverse field in a logical bidirectional relation.
To create a logical bidirectional relation in OpenJPA, use the
<ulink url="../javadoc/org/apache/openjpa/persistence/InverseLogical.html">
<classname>org.apache.openjpa.persistence.InverseLogical</classname></ulink>
annotation. We discuss logical bidirectional relations and this
extension in detail in <xref linkend="ref_guide_inverses"/>.
</para>
</section>
<section id="read-only">
<title>
Read-Only
</title>
<indexterm zone="read-only">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
read-only
</tertiary>
<seealso>
persistent fields
</seealso>
</indexterm>
<indexterm zone="read-only">
<primary>
persistent fields
</primary>
<secondary>
read only
</secondary>
</indexterm>
<para>
The read-only extension makes a field unwritable. The extension only applies to
existing persistent objects; new object fields are always writeable.
</para>
<para>
To mark a field read-only in JPA metadata, set the
<ulink url="../javadoc/org/apache/openjpa/persistence/ReadOnly.html">
<classname>org.apache.openjpa.persistence.ReadOnly</classname></ulink>
annotation to an
<ulink url="../javadoc/org/apache/openjpa/persistence/UpdateAction.html">
<classname>org.apache.openjpa.persistence.UpdateAction</classname></ulink> enum
value. The <classname>UpdateAction</classname> enum includes:
</para>
<itemizedlist>
<listitem>
<para>
<literal>UpdateAction.IGNORE</literal>: Updates to the field are completely
ignored. The field is not considered dirty. The new value will not even get
stored in the OpenJPA <link linkend="ref_guide_cache">data cache</link>.
</para>
</listitem>
<listitem>
<para>
<literal>UpdateAction.RESTRICT</literal>: Any attempt to change the field will
result in an immediate exception.
</para>
</listitem>
</itemizedlist>
</section>
<section id="type">
<title>
Type
</title>
<indexterm zone="type">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
type
</tertiary>
<seealso>
persistent fields
</seealso>
</indexterm>
<para>
OpenJPA has three levels of support for relations:
</para>
<orderedlist>
<listitem>
<para>
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.
</para>
</listitem>
<listitem>
<para>
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.
</para>
</listitem>
<listitem>
<para>
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.
</para>
</listitem>
</orderedlist>
<para>
Clearly, when you declare a field's type to be another persistence-capable
class, OpenJPA uses level 1 support. By default, OpenJPA 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 <classname>java.io.Serializable</classname> interface. If you declare a
field to be of type <classname>Serializable</classname>, OpenJPA lumps it
together with <classname>java.lang.Object</classname> fields and other
non-interface, unrecognized field types, which are all assigned level 3 support.
</para>
<para>
With OpenJPA'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 <classname>Entity</classname> 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
<classname>Object</classname> uses level 3 support. This is useful when you have
an interface relation that may <emphasis role="bold">not</emphasis> hold other
persistent objects (recall that OpenJPA assumes interface fields will always
hold persistent instances by default).
</para>
<para>
This extension is also used with OpenJPA's externalization feature, described in
<xref linkend="ref_guide_pc_extern"/>.
</para>
<para>
OpenJPA defines the following type annotations for field values, collection,
array, and map elements, and map keys, respectively:
</para>
<itemizedlist>
<listitem>
<para>
<ulink url="../javadoc/org/apache/openjpa/persistence/Type.html"><classname>
org.apache.openjpa.persistence.Type</classname></ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="../javadoc/org/apache/openjpa/persistence/ElementType.html">
<classname>org.apache.openjpa.persistence.ElementType</classname></ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="../javadoc/org/apache/openjpa/persistence/KeyType.html"><classname>
org.apache.openjpa.persistence.KeyType</classname></ulink>
</para>
</listitem>
</itemizedlist>
</section>
<section id="externalizer">
<title>
Externalizer
</title>
<indexterm zone="externalizer">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
externalizer
</tertiary>
<seealso>
externalization
</seealso>
</indexterm>
<para>
The OpenJPA
<ulink url="../javadoc/org/apache/openjpa/persistence/Externalizer.html">
<classname>org.apache.openjpa.persistence.Externalizer</classname></ulink>
annotation names a method to transform a field value into a value of
another type. See <xref linkend="ref_guide_pc_extern"/> for details.
</para>
</section>
<section id="factory">
<title>
Factory
</title>
<indexterm zone="factory">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
factory
</tertiary>
<seealso>
externalization
</seealso>
</indexterm>
<para>
The OpenJPA
<ulink url="../javadoc/org/apache/openjpa/persistence/Factory.html"><classname>
org.apache.openjpa.persistence.Factory</classname></ulink> annotation
names a method to re-create a field value from its externalized form. See
<xref linkend="ref_guide_pc_extern"/> for details.
</para>
</section>
<section id="external-values">
<title>
External Values
</title>
<indexterm zone="factory">
<primary>
metadata
</primary>
<secondary>
extensions
</secondary>
<tertiary>
external values
</tertiary>
<seealso>
externalization
</seealso>
</indexterm>
<para>
The OpenJPA
<ulink url="../javadoc/org/apache/openjpa/persistence/ExternalValues.html">
<classname>org.apache.openjpa.persistence.ExternalValues</classname></ulink>
annotation declares values for transformation of simple fields to
different constant values in the datastore. See
<xref linkend="ref_guide_pc_extern_values"/> for details.
</para>
</section>
</section>
<section id="ref_guide_meta_example">
<title>
Example
</title>
<para>
The following example shows you how to specify extensions in metadata.
</para>
<example id="ref_guide_metaex">
<title>
OpenJPA Metadata Extensions
</title>
<programlisting>
import org.apache.openjpa.persistence.*;
@Entity
@DataCache(enabled=false)
public class Magazine
{
@ManyToMany
@LRS
private Collection&lt;Subscriber&gt; subscribers;
@ExternalValues({"true=1", "false=2"})
@Type(int.class)
private boolean weekly;
...
}
</programlisting>
</example>
</section>
<section id="ref_guide_meta_xml">
<title>
XML extensions
</title>
<para>
OpenJPA has extended the JPA 2.0 schema to include elements and attributes corresponding
to OpenJPA extended metadata and mapping annotations. The schema are contained in 2
files: <ulink url="http://openjpa.apache.org/builds/latest/docs/schema/extendable/extendable-orm.xsd">
extendable-orm.xsd</ulink> and
<ulink url="http://openjpa.apache.org/builds/latest/docs/schema/openjpa-orm.xsd">openjpa-orm.xsd</ulink>.
The extendable-orm.xsd file provides copies of some of the JPA 2.0 schema elements with additional schema to make it
extendable.
The openjpa-orm.xsd file extends the extendable-orm.xsd with OpenJPA specific elements and attributes representing
OpenJPA annotations. Currently, only a subset of annotations have actually been implemented, and some of those
have been partially tested. The current status can be found by comments in the
<ulink url="http://openjpa.apache.org/builds/latest/docs/schema/openjpa-orm.xsd">openjpa-orm.xsd</ulink>
schema file.
</para>
<para>
In order to use the OpenJPA extensions in your mapping file you must include the namespaces for these 2 new
schemas as well as for the schema for JPA 2.0, as shown in the following example:
</para>
<example id="ref_guide_schema_ex">
<title>
OpenJPA Schema Extensions
</title>
<programlisting>
&lt;entity-mappings xmlns="http://www.apache.org/openjpa/ns/orm/extendable"
xmlns:openjpa="http://www.apache.org/openjpa/ns/orm"
xmlns:orm="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0"&gt;
&lt;entity class="org.apache.openjpa.persistence.jdbc.annotations.MultiColumnVersionPC"
metadata-complete="true"&gt;
&lt;table name="MCV"/&gt;
&lt;attributes&gt;
&lt;id name="id"&gt;
&lt;orm:generated-value/&gt;
&lt;/id&gt;
&lt;basic name="id"/&gt;
&lt;basic name="name"/&gt;
&lt;/attributes&gt;
&lt;openjpa:entity version-strategy="version-numbers"&gt;
&lt;openjpa:version-columns&gt;
&lt;openjpa:version-column name="v1"/&gt;
&lt;openjpa:version-column name="v2"/&gt;
&lt;openjpa:version-column name="v3"
column-definition="FLOAT"
scale="3"
precision="10"/&gt;
&lt;/openjpa:version-columns&gt;
&lt;/openjpa:entity&gt;
&lt;/entity&gt;
&lt;/entity-mappings&gt;
</programlisting>
</example>
</section>
</section>
</chapter>