You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by mp...@apache.org on 2006/08/22 23:28:55 UTC
svn commit: r433761 [14/18] - in /incubator/openjpa/trunk/openjpa-project:
./ src/doc/manual/
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_meta.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_meta.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_meta.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_meta.xml Tue Aug 22 14:28:53 2006
@@ -0,0 +1,976 @@
+
+ <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="../apidocs/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="../apidocs/org/apache/openjpa/persistence/PersistenceMetaDataFactory.html"><classname>
+ org.apache.openjpa.persistence.PersistenceMetaDataFactory</classname></ulink>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The standard metadata factories all accept the following properties for
+ locating persistent classes. Each 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
+ <phrase>annotated JPA entities</phrase>
+
+
+ .
+ </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
+ <phrase>annotated JPA entities</phrase>
+
+
+ .
+ </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
+ <phrase>annotated JPA entities</phrase>
+
+
+ .
+ </para>
+ </listitem>
+ </itemizedlist>
+ <example id="ref_guide_meta_stdfactoryex">
+ <title>Setting a Standard Metadata Factory</title>
+ <programlisting format="linespecific">
+<property name="openjpa.MetaDataFactory" value="jpa"/>
+</programlisting>
+ </example>
+ <example id="ref_guide_meta_customfactoryex">
+ <title>Setting a Custom Metadata Factory</title>
+ <programlisting format="linespecific">
+<property name="openjpa.MetaDataFactory" value="com.xyz.CustomMetaDataFactory"/>
+</programlisting>
+ </example>
+ </section>
+ <section id="ref_guide_meta_ejb">
+ <title>Additional JPA Metadata</title>
+ <indexterm zone="ref_guide_meta_ejb">
+ <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_ejb"/>.
+ 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="../apidocs/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 expands collection support to handle
+ collections of simple types (primitive wrappers,
+ <classname>String</classname>s, etc), custom types, and embedded
+ objects.
+ </para>
+ <para>
+ The
+ <ulink url="../apidocs/org/apache/openjpa/persistence/PersistentCollection.html"><classname>org.apache.openjpa.persistence.PersistentCollection</classname></ulink>
+ metadata annotation represents a 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>
+ <para><xref linkend="ref_guide_mapping_jpa_coll"/> contains several
+ examples of using <classname>PersistentCollection</classname> to
+ mark non-standard collection fields persistent.
+ </para>
+ </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. OpenJPA introduces the
+ <ulink url="../apidocs/org/apache/openjpa/persistence/PersistentMap.html"><classname>org.apache.openjpa.persistence.PersistentMap</classname></ulink>
+ metadata annotation to represent a persistent map field.
+ 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>
+ <para>
+ Map keys and values in OpenJPA can be entities, simple types
+ (primitive wrappers, <classname>String</classname>s, etc),
+ custom types, or embedded objects.
+ <xref linkend="ref_guide_mapping_jpa_map"/> contains several
+ examples of using <classname>PersistentMap</classname> to annotate
+ persistent map fields.
+ </para>
+ </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="data-cache">
+ <primary>metadata</primary>
+ <secondary>extensions</secondary>
+ <tertiary>fetch groups</tertiary>
+ <seealso>fetch groups</seealso>
+ </indexterm>
+ <para>
+
+ The
+ <ulink url="../apidocs/org/apache/openjpa/persistence/FetchGroups.html"><classname>org.apache.openjpa.persistence.FetchGroups</classname></ulink>
+ and <ulink url="../apidocs/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="../apidocs/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>String name</literal>: 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 <link linkend="openjpa.DataCache"><literal>
+ openjpa.DataCache</literal></link> configuration property
+ for base classes.
+ </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>
+ <para>
+ The <literal>data-cache</literal> key accepts the
+ following values:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>true</literal>: Use the default cache, as
+ configured by the <link linkend="openjpa.DataCache"><literal>openjpa.DataCache</literal></link> configuration
+ property. This is the default when no extension is
+ given, unless a superclass names a different cache.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>false</literal>: Data for instances of this
+ class should not be cached.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal><cache-name></literal>: Place data for
+ instances of this class into the cache with name
+ <literal><cache-name></literal>.
+ </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 supress 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="../apidocs/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 id="lock-groups">
+ <title>Lock Groups</title>
+ <para>
+ OpenJPA requires you to pre-declare subclass lock groups in the
+ least-derived mapped class.
+ <phrase>
+ The JPA
+ <ulink url="../apidocs/org/apache/openjpa/persistence/LockGroups.html"><classname>org.apache.openjpa.persistence.LockGroups</classname></ulink>
+ annotation accepts an array of lock group names.
+ </phrase>
+
+ For details on lock groups, see
+ <xref linkend="ref_guide_lock_groups_and_subclasses"/>.
+ </para>
+ </section>
+ <section id="auditable">
+ <title>Auditable</title>
+ <para>
+ Reserved for future use.
+ </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="data-cache">
+ <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>.
+ You can prevent an orphaned dependent object from being 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="../apidocs/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="../apidocs/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="../apidocs/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="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
+ <phrase>
+ the JPA <ulink url="../apidocs/org/apache/openjpa/persistence/LRS.html"><classname>org.apache.openjpa.persistence.LRS</classname></ulink> annotation,
+ </phrase>
+
+
+ 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="order-by">
+ <title>Order-By</title>
+ <indexterm zone="order-by">
+ <primary>metadata</primary>
+ <secondary>extensions</secondary>
+ <tertiary>order-by</tertiary>
+ </indexterm>
+ <para><phrase>
+ The JPA Overview's
+ <xref linkend="jpa_overview_meta_orderby"/> describes JPA's
+ <literal>OrderBy</literal> annotation for loading the elements
+ of collection fields in a prescribed order.
+ </phrase>
+
+
+
+ Ordering syntax is as follows:
+ </para>
+ <programlisting format="linespecific">
+#element|<field name>[ asc|ascending|desc|descending][, ...]
+</programlisting>
+ <para>
+ The token <literal>#element</literal> 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 <literal>
+ #element</literal> token, you can order a collection of
+ persistent objects by an arbitrary field in the related type,
+ rather than by primary key.
+ </para>
+ <para>
+ The field name or <literal>#element</literal> token may be
+ followed by the keywords <literal>asc/ascending</literal> or
+ <literal>desc/descending</literal> in either all-upper or
+ all-lower case to mandate ascending and descending order.
+ If the direction is omitted, OpenJPA defaults to ascending order.
+ </para>
+ <para>
+ Note that the defined ordering is only applied when the
+ collection is loaded from the datastore. It is not maintained
+ by OpenJPA as you modify the collection in memory.
+ </para>
+ <para>
+ The following ordering string orders a collection by its
+ element values in descending order:
+ </para>
+ <programlisting format="linespecific">
+"#element desc"
+</programlisting>
+ <para>
+ The following ordering string orders a collection of
+ <classname>Author</classname> 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.
+ </para>
+ <programlisting format="linespecific">
+"firstName, lastName"
+</programlisting>
+ </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.
+ <phrase>
+ To create a logical bidrectional relation in OpenJPA, use the
+ <ulink url="../apidocs/org/apache/openjpa/persistence/InverseLogical.html"><classname>org.apache.openjpa.persistence.InverseLogical</classname></ulink>
+ annotation.
+ </phrase>
+
+ We discuss logical bidirectional relations and this extension
+ in detail in <xref linkend="ref_guide_inverses"/>.
+ </para>
+ </section>
+ <section id="lock-group">
+ <title>Lock Group</title>
+ <indexterm zone="lock-group">
+ <primary>metadata</primary>
+ <secondary>extensions</secondary>
+ <tertiary>lock group</tertiary>
+ <seealso>locking</seealso>
+ </indexterm>
+ <para>
+ Lock groups allow for fine-grained optimistic locking
+ concurrency.
+ Use
+ <phrase>
+ OpenJPA's
+ <ulink url="../apidocs/org/apache/openjpa/persistence/LockGroup.html"><classname>org.apache.openjpa.persistence.LockGroup</classname></ulink>
+ annotation
+ </phrase>
+
+
+ to name the lock group for a field. You can exclude a field
+ from optimistic locking with a value of <literal>none</literal>.
+ We discuss lock groups and this extension further in
+ <xref linkend="ref_guide_lock_groups"/>.
+ </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="../apidocs/org/apache/openjpa/persistence/ReadOnly.html"><classname>org.apache.openjpa.persistence.ReadOnly</classname></ulink>
+ annotation to a
+ <ulink url="../apidocs/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
+ <phrase><classname>Entity</classname></phrase>
+
+
+
+ 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="../apidocs/org/apache/openjpa/persistence/Type.html">
+ <classname>org.apache.openjpa.persistence.Type</classname>
+ </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../apidocs/org/apache/openjpa/persistence/ElementType.html">
+ <classname>org.apache.openjpa.persistence.ElementType
+ </classname>
+ </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="../apidocs/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
+ <phrase>
+ JPA
+ <ulink url="../apidocs/org/apache/openjpa/persistence/Externalizer.html"><classname>org.apache.openjpa.persistence.Externalizer</classname></ulink>
+ annotation
+ </phrase>
+
+
+ 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
+ <phrase>
+ JPA <ulink url="../apidocs/org/apache/openjpa/persistence/Factory.html"><classname>org.apache.openjpa.persistence.Factory</classname></ulink>
+ annotation
+ </phrase>
+
+
+ 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
+ <phrase>
+ JPA
+ <ulink url="../apidocs/org/apache/openjpa/persistence/ExternalValues.html"><classname>org.apache.openjpa.persistence.ExternalValues</classname></ulink>
+ annotation
+ </phrase>
+
+
+ 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 format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+@Entity
+@DataCache(enabled=false)
+public class Magazine
+{
+ @ManyToMany
+ @LRS
+ @LockGroup(LockGroup.NONE)
+ private Collection<Subscriber> subscribers;
+
+ @ExternalValues({"true=1", "false=2"})
+ @Type(int.class)
+ private boolean weekly;
+
+ @PersistentCollection
+ @OrderBy("#element DESC")
+ private List<String> subtitles;
+
+ ...
+}
+</programlisting>
+ </example>
+ </section>
+ </section>
+ </chapter>
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_optimization.xml Tue Aug 22 14:28:53 2006
@@ -0,0 +1,666 @@
+
+ <chapter id="ref_guide_optimization">
+ <title>Optimization Guidelines</title>
+ <indexterm zone="ref_guide_optimization">
+ <primary>optimization guidelines</primary>
+ </indexterm>
+ <para>
+ There are numerous techniques you can use in order to ensure that OpenJPA
+ operates in the fastest and most efficient manner. Following are some
+ guidelines. Each describes what impact it will have on performance and
+ scalability. Note that general guidelines regarding performance or
+ scalability issues are just that - guidelines. Depending on the
+ particular characteristics of your application, the optimal settings
+ may be considerably different than what is outlined below.
+ </para>
+ <para>
+ In the following table, each row is labeled with a list of
+ italicized keywords. These keywords identify what characteristics
+ the row in question may improve upon. Many of the rows are marked with
+ one or both of the <emphasis>performance</emphasis> and
+ <emphasis>scalability</emphasis> labels. It is important to bear
+ in mind the differences between performance and scalability (for the
+ most part, we are referring to system-wide scalability, and not
+ necessarily only scalability within a single JVM). The
+ performance-related hints will probably improve the performance of
+ your application for a given user load, whereas the
+ scalability-related hints will probably increase the total number of
+ users that your application can service. Sometimes, increasing
+ performance will decrease scalability, and vice versa. Typically,
+ options that reduce the amount of work done on the database server
+ will improve scalability, whereas those that push more work onto the
+ server will have a negative impact on scalability.
+ </para>
+ <table>
+ <title>Optimization Guidelines</title>
+ <tgroup cols="2" align="left" colsep="1" rowsep="1">
+ <colspec colname="name"/>
+ <colspec colname="desc" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Optimize database indexes</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ The default set of indexes created by OpenJPA's mapping
+ tool may not always be the most appropriate for your
+ application. Manually setting indexes in your mapping
+ metadata or manually manipulating database indexes to
+ include frequently-queried fields (as well as dropping
+ indexes on rarely-queried fields) can yield significant
+ performance benefits.
+ <para>
+ A database must do extra work on insert, update, and
+ delete to maintain an index. This extra work will benefit
+ selects with WHERE clauses, which will execute much faster
+ when the terms in the WHERE clause are appropriately
+ indexed. So, for a read-mostly application, appropriate
+ indexing will slow down updates (which are rare) but greatly
+ accelerate reads. This means that the system as a whole will
+ be faster, and also that the database will experience less
+ load, meaning that the system will be more scalable.
+ </para>
+ <para>
+ Bear in mind that over-indexing is a bad thing, both
+ for scalability and performance, especially for applications
+ that perform lots of inserts, updates, or deletes.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use the best JDBC driver</emphasis>
+ <para>
+ <emphasis>performance, scalability, reliability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ The JDBC driver provided by the database vendor is not
+ always the fastest and most efficient. Some JDBC drivers
+ do not support features like batched statements, the lack
+ of which can significantly slow down OpenJPA's data access
+ and increase load on the database, reducing system
+ performance and scalability.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">JVM optimizations</emphasis>
+ <para>
+ <emphasis>performance, reliability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ Manipulating various parameters of the Java Virtual Machine
+ (such as hotspot compilation modes and the maximum memory)
+ can result in performance improvements. For more details
+ about optimizing the JVM execution environment, please see
+ <ulink url="http://java.sun.com/docs/hotspot/PerformanceFAQ.html"/>.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use the data cache</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ Using OpenJPA's <link linkend="ref_guide_cache">data and
+ query caching</link> features can often result
+ in a dramatic improvement in performance. Additionally,
+ these caches can significantly reduce the amount of load on
+ the database, increasing the scalability characteristics of
+ your application. Also, be sure to read about the
+ <link linkend="ref_guide_cache_concurrent">concurrent cache
+ </link> option to see if it fits your needs.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Set <literal>LargeTransaction
+ </literal> to true, or set <literal>PopulateDataCache
+ </literal> to false</emphasis>
+ <para>
+ <emphasis>performance vs. scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ When using OpenJPA's <link linkend="ref_guide_cache">data
+ caching</link> features (available in OpenJPA JDO
+ Performance Pack and Enterprise Edition)
+ in a transaction that will delete, modify, or create
+ a very large number of objects you can set <literal>
+ LargeTransaction</literal> to true and perform periodic
+ flushes during your transaction to reduce its memory
+ requirements. See the Javadoc:
+ <phrase><ulink url="javadoc/openjpa/persistence/OpenJPAEntityManager.html">
+ OpenJPAEntityManager.setLargeTransaction</ulink></phrase>
+
+
+ Note that transactions in large mode have to
+ more aggressively flush items from the data cache.
+ <para>
+ If your transaction will visit objects that you know
+ are very unlikely to be accessed by other transactions,
+ for example an exhaustive report run only once a month,
+ you can turn off population of the data cache so that
+ the transaction doesn't fill the entire data cache with
+ objects that won't be accessed again.
+ Again, see the Javadoc:
+ <phrase><ulink url="javadoc/openjpa/persistence/OpenJPAEntityManager.html">
+ OpenJPAEntityManager.setPopulateDataCache</ulink></phrase>
+
+
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Disable logging, performance
+ tracking</emphasis>
+ <para>
+ <emphasis>performance</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ Developer options such as verbose logging and the
+ JDBC performance tracker can result in serious performance
+ hits for your application. Before evaluating OpenJPA's
+ performance, these options should all be disabled.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Set <literal>IgnoreChanges</literal>
+ to true, or set <literal>FlushBeforeQueries</literal> to
+ true</emphasis>
+ <para>
+ <emphasis>performance vs. scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ When both the <link linkend="openjpa.IgnoreChanges"><literal>openjpa.IgnoreChanges</literal></link> and
+ <link linkend="openjpa.FlushBeforeQueries"><literal>
+ openjpa.FlushBeforeQueries</literal></link> properties are set
+ to false, OpenJPA needs to consider in-memory dirty instances
+ during queries. This can sometimes result in OpenJPA needing
+ to evaluate the entire extent objects in order to
+ return the correct query results, which can have drastic
+ performance consequences. If it is appropriate for your
+ application, configuring
+ <literal>FlushBeforeQueries</literal>
+ to automatically flush before queries involving dirty
+ objects will ensure that this never
+ happens. Setting <literal>IgnoreChanges</literal> to
+ false will result in a small performance hit even if
+ <literal>FlushBeforeQueries</literal> is true, as
+ incremental flushing is not as efficient overall as
+ delaying all flushing to a single operation during commit.
+ This is because incrementally flushing decreases OpenJPA's
+ ability to maximize statement batching, and increases
+ resource utilization.
+ <para>
+ Note that the default setting of
+ <literal>FlushBeforeQueries</literal> is
+ <literal>with-connection</literal>, which means that data
+ will be flushed only if a dedicated connection is already
+ in use by the <classname>EntityManager</classname>.
+ So, the default value may not be appropriate for you.
+ </para>
+
+
+ <para>
+ Setting <literal>IgnoreChanges</literal> to
+ <literal>true</literal> will help performance, since dirty
+ objects can be ignored for queries, meaning that
+ incremental flushing or client-side processing
+ is not necessary. It will also improve scalability, since
+ overall database server usage is diminished. On the other
+ hand, setting <literal>IgnoreChanges</literal> to
+ <literal>false</literal> will have a negative impact on
+ scalability, even when using automatic flushing before
+ queries, since more operations will be performed on the
+ database server.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Configure <literal>
+ openjpa.ConnectionRetainMode</literal> appropriately</emphasis>
+ <para>
+ <emphasis>performance vs. scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ The <link linkend="openjpa.ConnectionRetainMode"><literal>
+ ConnectionRetainMode</literal></link> configuration option
+ controls when OpenJPA will obtain a connection, and how long
+ it will hold that connection. The optimal settings for this
+ option will vary considerably depending on the particular
+ behavior of your application. You may even benefit from
+ using different retain modes for different parts of your
+ application.
+ <para>
+ The default setting of <literal>on-demand</literal>
+ minimizes the amount of time that OpenJPA holds onto a
+ datastore connection. This is generally the best option
+ from a scalability standpoind, as database resources are
+ held for a minimal amount of time. However, if your
+ connection pool is overly small relative to the number of
+ concurrent sessions that need access to the
+ database, or if your <classname>DataSource</classname> is
+ not efficient at managing its pool, then this default value
+ could cause undesirable pool contention.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Ensure that batch updates are
+ available</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ When performing bulk inserts, updates, or deletes, OpenJPA
+ will use batched statements. If this feature is not
+ available in your JDBC driver, then OpenJPA will need to
+ issue multiple SQL statements instead of a single batch
+ statement.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use
+ flat inheritance</emphasis>
+ <para>
+ <emphasis>performance, scalability vs. disk space</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ Mapping inheritance hierarchies to a single database table
+ is faster for most operations than other strategies
+ employing multiple tables. If it is appropriate for your
+ application, you should use this strategy whenever possible.
+ <para>
+ However, this strategy will require more disk
+ space on the database side. Disk space is relatively
+ inexpensive, but if your object model is particularly
+ large, it can become a factor.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">High sequence increment</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ For applications that perform large bulk inserts, the
+ retrieval of sequence numbers can be a bottleneck.
+ Increasing sequence increments and using table-based rather
+ than native database sequences can reduce or eliminate
+ this bottleneck. In some cases,
+ implementing your own sequence factory can further optimize
+ sequence number retrieval.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use optimistic transactions</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ Using datastore transactions translates into pessimistic
+ database row locking, which can be a performance hit
+ (depending on the database). If appropriate for your
+ application, optimistic transactions are typically faster
+ than datastore transactions.
+ <para>
+ Optimistic transactions provide the same transactional
+ guarantees as datastore transactions, except that you must
+ handle a potential optimistic verification exception at the
+ end of a transaction instead of assuming that a transaction
+ will successfully complete. In many applications, it is
+ unlikely that different concurrent transactions will operate
+ on the same set of data at the same time, so optimistic
+ verification increases the concurrency, and therefore both
+ the performance and scalability characteristics, of the
+ application. A common approach to handling optimistic
+ verification exceptions is to simply present the end user
+ with the fact that concurrent modifications happened, and
+ require that the user redo any work.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use query aggregates and projections
+ </emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ Using aggregates to compute reporting data on the database
+ server can drastically speed up queries. Similarly, using
+ projections when you are interested in specific
+ object fields or relations rather than the entire object
+ state can reduce the amount of data OpenJPA must transfer
+ from the database to your application.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Always close resources</emphasis>
+ <para>
+ <emphasis>scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ <para>
+ Under certain settings, <classname>
+ EntityManager</classname>s, OpenJPA <classname>Extent
+ </classname> iterators, and <classname>Query</classname>
+ results may be backed by resources in the database.
+ </para>
+ <para>
+ For example, if you have
+ configured OpenJPA to use scrollable cursors and lazy object
+ instantiation by default, each query result will hold open
+ a <classname>ResultSet</classname> object, which, in turn,
+ will hold open a <classname>Statement</classname> object
+ (preventing it from being re-used). Garbage collection
+ will clean up these resources, so it is never necessary to
+ explicitly close them, but it is always faster if it is
+ done at the application level.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Optimize connection pool
+ settings</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ <para>
+ OpenJPA's built-in connection pool's default settings may
+ not be optimal for all applications. For applications that
+ instantiate and close many <classname>
+ EntityManager</classname>s (such as a
+ web application), increasing the size of the connection
+ pool will reduce the overhead of waiting on free connections
+ or opening new connections.
+ </para>
+ <para>
+ You may want to tune the
+ prepared statement pool size with the connection pool size.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use detached state managers</emphasis>
+ <para>
+ <emphasis>performance</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ <para>
+ Attaching and even persisting instances can be more
+ efficient when your detached objects use detached state
+ managers. By default, OpenJPA does not use detached state
+ managers when serializing an instance across tiers. See
+ <xref linkend="ref_guide_detach_graph"/> for how to force
+ OpenJPA to use detached state managers across tiers, and for
+ other options for more efficient attachment.
+ </para>
+ <para>
+ The downside of using a detached state manager
+ across tiers is that your enhanced persistent classes and
+ the OpenJPA libraries must be available on the client tier.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Utilize the <classname>
+ EntityManager</classname> cache</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ When possible and appropriate, re-using <classname>
+ EntityManager</classname>s and setting the
+ <link linkend="openjpa.RetainState"><literal>
+ RetainState</literal></link> configuration option to
+ <literal>true</literal> may result in significant
+ performance gains, since the <classname>
+ EntityManager</classname>'s built-in
+ object cache will be used.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Enable multithreaded operation only
+ when necessary</emphasis>
+ <para>
+ <emphasis>performance</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ OpenJPA respects the <link linkend="openjpa.Multithreaded"><literal>openjpa.Multithreaded</literal></link> option in
+ that it does not impose synchronization overhead for
+ applications that set this value to
+ <literal>false</literal>. If your application is
+ guaranteed to only use single-threaded access to OpenJPA
+ resources and persistent objects, setting this option to
+ <literal>false</literal> will result
+ in the elimination of synchronization overhead, and may
+ result in a modest performance increase.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Enable large data set
+ handling</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ If you execute queries that return large numbers of objects
+ or have relations (collections or maps) that are large, and
+ if you often only access parts of these data sets, enabling
+ <link linkend="ref_guide_dbsetup_lrs">large result set
+ handling</link> where appropriate can
+ dramatically speed up your application, since OpenJPA will
+ bring the data sets into memory from the database only as
+ necessary.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Disable large data set handling
+ </emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ If you have enabled scrollable result sets and on-demand
+ loading but do you not require it, consider disabling it
+ again. Some JDBC drivers and databases (SQLServer for
+ example) are much slower when used with scrolling result
+ sets.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use short discriminator values, or
+ turn off the discriminator
+ </emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ The default discriminator strategy of storing the class
+ name in the discriminator column is quite robust, in that
+ it can handle any class and needs no configuration, but
+ the downside of this robustness is that it puts a
+ relatively lengthy string into each row of the database.
+ With a little application-specific configuration, you can
+ easily reduce this to a single character or integer. This
+ can result in significant performance gains when dealing
+ with many small objects,
+ since the subclass indicator data can become a significant
+ proportion of the data transferred between the JVM and
+ the database.
+ <para>
+ Alternately, if certain persistent classes in your
+ application do not make use of inheritance, then you can
+ disable the discriminator for these classes altogether.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use the <classname>
+ DynamicSchemaFactory</classname></emphasis>
+ <para>
+ <emphasis>performance, validation</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ If you are using a <link linkend="openjpa.jdbc.SchemaFactory"><literal>openjpa.jdbc.SchemaFactory</literal></link> setting
+ of something other than the default of <literal>
+ dynamic</literal>, consider switching back. While other
+ factories can ensure that object-relational mapping
+ information is valid when a persistent class is first used,
+ this can be a slow process. Though the validation is only
+ performed once for each class, switching back to the
+ <classname>DynamicSchemaFactory</classname>
+ can reduce the warm-up time for your application.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Do not use XA transactions</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc"><link linkend="ref_guide_enterprise_xa">XA transactions
+ </link> can be orders of magnitude slower than standard
+ transactions. Unless distributed transaction functionality
+ is required by your application, use standard transactions.
+ <para>
+ Recall that XA transactions are distinct from
+ managed transactions - managed transaction services
+ such as that provided by EJB declarative transactions
+ can be used both with XA and non-XA transactions. XA
+ transactions should only be used when a given business
+ transaction involves multiple different transactional
+ resources (an Oracle database and an IBM transactional
+ message queue, for example).
+ </para></entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use <classname>Set</classname>s
+ instead of <classname>List/Collection</classname>s
+ </emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ There is a small amount of extra overhead for OpenJPA to
+ maintain collections where each element is not guaranteed
+ to be unique. If your application does not require
+ duplicates for a collection, you should always declare your
+ fields to be of type <classname>Set, SortedSet,
+ HashSet,</classname> or <classname>TreeSet</classname>.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use query parameters instead of
+ encoding search data in filter strings</emphasis>
+ <para>
+ <emphasis>performance</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ If your queries depend on parameter data only known at
+ runtime, you should use query parameters rather than
+ dynamically building different query strings. OpenJPA
+ performs aggressive caching of query compilation
+ data, and the effectiveness of this cache is diminished if
+ multiple query filters are used where a single one could
+ have sufficed.
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Tune your fetch groups
+ appropriately</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ The <link linkend="ref_guide_fetch">fetch groups</link>
+ used when loading an object control how much data is
+ eagerly loaded, and by extension, which fields must be
+ lazily loaded at a future time. The ideal fetch group
+ configuration loads all the data that is needed in one
+ fetch, and no extra fields - this minimizes both the
+ amount of data transferred from the database, and the
+ number of trips to the database.
+ <para>
+ If extra fields are specified in the fetch groups
+ (in particular, large fields such as binary data, or
+ relations to other persistence-capable objects), then
+ network overhead (for the extra data) and database
+ processing (for any necessary additional joins) will
+ hurt your application's performance. If too few fields
+ are specified in the fetch groups, then OpenJPA will have
+ to make additional trips to the database to load
+ additional fields as necessary.
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry colname="name">
+ <emphasis role="bold">Use eager fetching</emphasis>
+ <para>
+ <emphasis>performance, scalability</emphasis>
+ </para>
+ </entry>
+ <entry colname="desc">
+ Using <link linkend="ref_guide_perfpack_eager">eager
+ fetching</link> when loading subclass data or traversing
+ relations for each instance in a large collection of
+ results can speed up data loading by orders of magnitude.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </chapter>