openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mprud...@apache.org
Subject svn commit: r433761 [15/18] - in /incubator/openjpa/trunk/openjpa-project: ./ src/doc/manual/
Date Tue, 22 Aug 2006 21:28:55 GMT
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_pc.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_pc.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_pc.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_pc.xml Tue Aug 22 14:28:53 2006
@@ -0,0 +1,2488 @@
+
+    <chapter id="ref_guide_pc">
+      <title>Persistent Classes</title>
+      <indexterm zone="ref_guide_pc">
+        <primary>persistent classes</primary>
+      </indexterm>
+      <para>
+  Persistent class basics are covered in 
+  <xref linkend="jpa_overview_pc"/> of the JPA Overview.  
+  This chapter details the persistent class features OpenJPA offers beyond the 
+  core JPA specification.
+  </para>
+      <section id="ref_guide_pc_pcclasses">
+        <title>Persistent Class List</title>
+        <indexterm zone="ref_guide_pc_pcclasses">
+          <primary>persistent classes</primary>
+          <secondary>list</secondary>
+        </indexterm>
+        <indexterm zone="ref_guide_pc_pcclasses">
+          <primary>PCClasses</primary>
+        </indexterm>
+        <para>
+    Unlike many ORM products, OpenJPA does not need to know about all of your
+    persistent classes at startup.  OpenJPA discovers new persistent classes 
+    automatically as they are loaded into the JVM; in fact you can introduce
+    new persistent classes into running applications under OpenJPA.  However,
+    there are certain situations in which providing OpenJPA with a persistent
+    class list is helpful:
+    </para>
+        <itemizedlist>
+          <listitem>
+            <para>
+        OpenJPA must be able to match entity names in JPQL queries to 
+        persistent classes.  OpenJPA automatically knows the entity names
+        of any persistent classes already loaded into the JVM.  To match
+        entity names to classes that have not been loaded, however,
+        you must supply a persistent class list.
+        </para>
+          </listitem>
+          <listitem>
+            <para>
+        When OpenJPA manipulates classes in a persistent inheritance
+        hierarchy, OpenJPA must be aware of all the classes in the
+        hierarchy.  If some of the classes have not been loaded into the
+        JVM yet, OpenJPA may not know about them, and queries may return
+        incorrect results.
+        </para>
+          </listitem>
+          <listitem>
+            <para>
+        If you configure OpenJPA to create the needed database schema
+        on startup (see <xref linkend="ref_guide_mapping_synch"/>),
+        OpenJPA must know all of your persistent classes up-front.
+        </para>
+          </listitem>
+        </itemizedlist>
+        <para>
+    When any of these conditions are a factor in your JPA 
+    application, use the <literal>class</literal>, <literal>
+    mapping-file</literal>, and <literal>jar-file</literal> elements of 
+    JPA's standard XML format to list your 
+    persistent classes.  See
+    <xref linkend="jpa_overview_persistence_xml"/> for details.
+    </para>
+        <note>
+          <para>
+      Listing persistent classes (or their metadata or jar files) is an 
+      all-or-nothing endeavor.  If your persistent class list is 
+      non-empty, OpenJPA will assume that any unlisted class is not 
+      persistent.
+      </para>
+        </note>
+      </section>
+      <section id="ref_guide_pc_enhance">
+        <title>Enhancement</title>
+        <indexterm zone="ref_guide_pc_enhance">
+          <primary>enhancer</primary>
+        </indexterm>
+        <indexterm>
+          <primary>openjpac</primary>
+          <see>enhancer</see>
+        </indexterm>
+        <para>
+    In order to provide optimal runtime performance, flexible lazy loading,
+    and efficient, immediate dirty tracking, OpenJPA uses an <emphasis>
+    enhancer</emphasis>.  An enhancer is a tool that automatically adds 
+    code to your persistent classes after you have written them.
+    The enhancer post-processes the bytecode generated by your Java 
+    compiler, adding the necessary fields and methods to implement the 
+    required persistence features.  This bytecode modification perfectly 
+    preserves the line numbers in stack traces and is compatible with Java 
+    debuggers.
+    <phrase>
+    In fact, the only change to debugging is that the persistent setter 
+    and getter methods of entity classes using property access will be
+    prefixed with <literal>pc</literal> in stack traces and 
+    step-throughs.
+    For example, if your entity has a <methodname>getId</methodname> method
+    for persistent property <literal>id</literal>, and that method throws 
+    an exception, the stack trace will report the exception from method 
+    <methodname>pcgetId</methodname>.  The line numbers, however, will
+    correctly correspond to the <methodname>getId</methodname> method 
+    in your source file.
+    </phrase>
+    </para>
+        <mediaobject>
+          <imageobject>
+<!-- PNG image data, 509 x 133 (see README) -->
+            <imagedata fileref="img/enhancement.png" width="339px"/>
+          </imageobject>
+        </mediaobject>
+        <para>
+    The diagram above illustrates the compilation of a persistent class.
+    </para>
+        <para>
+    You can add the OpenJPA enhancer to your build process, 
+    or use Java 1.5's new instrumentation features to transparently enhance
+    persistent classes when they are loaded into the JVM.  The following 
+    sections describe each option.
+    </para>
+        <section id="ref_guide_pc_enhance_build">
+          <title>Enhancing at Build Time</title>
+          <indexterm zone="ref_guide_pc_enhance_build">
+            <primary>enhancer</primary>
+            <secondary>build time</secondary>
+          </indexterm>
+          <para>
+      The enhancer can be invoked at build time via the
+      included <literal>openjpac</literal> script or via its Java class, 
+      <classname>org.apache.openjpa.enhance.PCEnhancer</classname>.
+      </para>
+          <note>
+            <para>
+        You can also enhance via Ant; see
+        <xref linkend="ref_guide_integration_enhance"/>.
+        </para>
+          </note>
+          <example id="ref_guide_pc_enhance_enhancer">
+            <title>Using the OpenJPA Enhancer</title>
+            <programlisting format="linespecific">
+openjpac Magazine.java
+</programlisting>
+          </example>
+          <para>
+      The enhancer accepts the standard set of command-line arguments 
+      defined by the configuration framework
+      (see <xref linkend="ref_guide_conf_devtools"/>), along with the
+      following flags:
+      </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>-directory/-d &lt;output directory&gt;</literal>: 
+          Path to the output directory.  If the directory does not 
+          match the enhanced class' package, the package structure 
+          will be created beneath the directory.  By default, the 
+          enhancer overwrites the original <filename>.class</filename>
+          file.
+          </para>
+            </listitem>
+            <listitem>
+              <para><literal>-enforcePropertyRestrictions/-epr &lt;true/t | 
+          false/f&gt;</literal>: Whether to throw an exception when
+          it appears that a property access entity is not obeying the
+          restrictions placed on property access.  Defaults to false.
+          </para>
+            </listitem>
+            <listitem>
+              <para><literal>-addDefaultConstructor/-adc &lt;true/t 
+          | false/f&gt;</literal>: The spec requires that all 
+          persistent classes define a no-arg constructor.  This flag 
+          tells the enhancer whether to add a protected no-arg 
+          constructor to any persistent classes that don't already 
+          have one.  Defaults to <literal>true</literal>.
+          </para>
+            </listitem>
+            <listitem>
+              <para><literal>-tmpClassLoader/-tcl &lt;true/t 
+          | false/f&gt;</literal>: Whether to load persistent classes
+          with a temporary class loader.  This allows other code to 
+          then load the enhanced version of the class within the same
+          JVM.  Defaults to <literal>true</literal>.  Try setting 
+          this flag to <literal>false</literal> as a debugging step 
+          if you run into class loading problems when running the 
+          enhancer.
+          </para>
+            </listitem>
+          </itemizedlist>
+          <para>
+      Each additional argument to the enhancer must be one of the 
+      following:
+      </para>
+          <itemizedlist>
+            <listitem>
+              <para>The full name of a class.</para>
+            </listitem>
+            <listitem>
+              <para>The .java file for a class.</para>
+            </listitem>
+            <listitem>
+              <para>
+          The <filename>.class</filename> file of a class.
+          </para>
+            </listitem>
+          </itemizedlist>
+          <para>
+      If you do not supply any arguments to the enhancer, it will run on
+      the classes in your persistent class list (see 
+      <xref linkend="ref_guide_pc_pcclasses"/>).
+      </para>
+          <para>
+      You can run the enhancer over classes that have already been 
+      enhanced, in which case it will not further modify the class.  You 
+      can also run it over classes that are not persistence-capable, in 
+      which case it will treat the class as persistence-aware.  
+      Persistence-aware classes can directly manipulate the persistent 
+      fields of persistence-capable classes.
+      </para>
+          <para>
+      Note that the enhancement process for subclasses introduces 
+      dependencies on the persistent parent class being enhanced.  This 
+      is normally not problematic; however, when running the enhancer 
+      multiple times over a subclass whose parent class is not yet 
+      enhanced, class loading errors can occur.  In the event of a class 
+      load error, simply re-compile and re-enhance the offending classes.
+      </para>
+        </section>
+        <section id="ref_guide_pc_enhance_runtime_container">
+          <title>Enhancing JPA Entities on Deployment</title>
+          <indexterm zone="ref_guide_pc_enhance_runtime_container">
+            <primary>enhancer</primary>
+            <secondary>runtime</secondary>
+            <tertiary>in an EJB container</tertiary>
+          </indexterm>
+          <para>
+      The JEE 5 specification includes hooks to automatically enhance
+      JPA entities when they are deployed into a container.  Thus, if you
+      are using a JEE 5-compliant application server, OpenJPA will enhance
+      your entities automatically at runtime.  Note that if you prefer
+      build-time enhancement, OpenJPA's runtime enhancer will correctly 
+      recognize and skip pre-enhanced classes.
+      </para>
+          <para>
+      If your application server does not support the JEE 5 enhancement
+      hooks, consider using the build-time enhancement described above,
+      or the more general runtime enhancement described in the next 
+      section.
+      </para>
+        </section>
+        <section id="ref_guide_pc_enhance_runtime">
+          <title>Enhancing at Runtime</title>
+          <indexterm zone="ref_guide_pc_enhance_runtime">
+            <primary>enhancer</primary>
+            <secondary>runtime</secondary>
+            <tertiary>outside a container</tertiary>
+          </indexterm>
+          <para>
+      OpenJPA includes a <emphasis>Java agent</emphasis> for automatically
+      enhancing persistent classes as they are loaded into the JVM.  
+      Java agents are classes that are invoked prior to your application's
+      <methodname>main</methodname> method.  OpenJPA's agent uses JVM 
+      hooks to intercept all class loading to enhance classes that
+      have persistence metadata before the JVM loads them.  
+      </para>
+          <note>
+            <para>
+        Java agents are new to Java 5; 
+        if you are using a previous Java version, you must use OpenJPA's
+        <link linkend="ref_guide_pc_enhance_build">build-time 
+        enhancement</link> option.
+        </para>
+          </note>
+          <para>
+      Searching for metadata for every class loaded by the JVM can slow
+      application initialization.  One way to speed things up is to
+      take advantage of the optional persistent class list described in
+      <xref linkend="ref_guide_pc_pcclasses"/>.  If you declare a 
+      persistent class list, OpenJPA will only search for metadata for
+      classes in that list. 
+      </para>
+          <para>
+      To employ the OpenJPA agent, invoke <literal>java</literal> with the
+      <literal>-javaagent</literal> set to the path to your 
+      <filename>org.apache.openjpa.jar</filename> or 
+      <filename>openjpa-runtime.jar</filename> file.
+      </para>
+          <example id="ref_guide_pc_enhance_runtime_ex">
+            <title>Using the OpenJPA Agent for Runtime Enhancement</title>
+            <programlisting format="linespecific">
+java -javaagent:/home/dev/openjpa/lib/org.apache.openjpa.jar com.xyz.Main
+</programlisting>
+          </example>
+          <para>
+      You can pass settings to the agent using OpenJPA's plugin syntax
+      (see <xref linkend="ref_guide_conf_plugins"/>).  The agent accepts
+      the long form of any of the standard configuration options
+      (<xref linkend="ref_guide_conf_devtools"/>).  It also accepts the
+      following options, the first three of which correspond exactly to
+      to the same-named options of the enhancer tool described in 
+      <xref linkend="ref_guide_pc_enhance_build"/>:
+      </para>
+          <itemizedlist>
+            <listitem>
+              <para>
+                <literal>addDefaultConstructor</literal>
+              </para>
+            </listitem>
+            <listitem>
+              <para>
+                <literal>jdoEnhance</literal>
+              </para>
+            </listitem>
+            <listitem>
+              <para>
+                <literal>enforcePropertyRestrictions</literal>
+              </para>
+            </listitem>
+            <listitem>
+              <para><literal>scanDevPath</literal>: Boolean indicating whether
+          to scan the classpath for persistent types if none have
+          been configured.  If you do not specify a persistent types
+          list and do not set this option to true, OpenJPA will check
+          whether each class loaded into the JVM is persistent, and
+          enhance it accordingly.  This may slow down class load times
+          significantly. 
+          </para>
+            </listitem>
+          </itemizedlist>
+          <example id="ref_guide_pc_enhance_runtime_opt_ex">
+            <title>Passing Options to the OpenJPA Agent</title>
+            <programlisting format="linespecific">
+java -javaagent:/home/dev/openjpa/lib/org.apache.openjpa.jar=jdoEnhance=true,addDefaultConstructor=false com.xyz.Main
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_pc_enhance_sercompat">
+          <title>Serializing Enhanced Types</title>
+          <indexterm zone="ref_guide_pc_enhance_sercompat">
+            <primary>enhancer</primary>
+            <secondary>serialization</secondary>
+            <tertiary>of enhanced types</tertiary>
+          </indexterm>
+          <indexterm zone="ref_guide_pc_enhance_sercompat">
+            <primary>serialization</primary>
+            <secondary>of enhanced types</secondary>
+          </indexterm>
+          <para>
+      By default, OpenJPA maintains serialization compatibility
+      between the enhanced and unenhanced versions of a class.  This 
+      allows you to serialize instances between a server using OpenJPA and
+      a client that does not have access to enhanced classes or OpenJPA 
+      libraries.  In some cases, however, you can make the persist and 
+      attach processes more robust and efficient by allowing breaks in 
+      serialization compatibility.  See 
+      <xref linkend="ref_guide_detach_graph"/> for details.
+      </para>
+        </section>
+      </section>
+<!-- ### proxy
+  <section id="ref_guide_pc_prop">
+    <title>Restrictions on Property Access Types</title>
+    <indexterm zone="ref_guide_pc_prop">
+      <primary>persistent classes</primary>
+      <secondary>property access restrictions</secondary>
+    </indexterm>
+    <indexterm zone="ref_guide_pc_prop">
+      <primary>property access</primary>
+      <secondary>restrictions</secondary>
+    </indexterm>
+    <para>
+    The JPA Overview explains the choice between property and 
+    field access for your entities and embeddable types in 
+    <xref linkend="jpa_overview_meta"/>.  As you saw in the previous 
+    section, OpenJPA uses an <emphasis>enhancer</emphasis> to transparently
+    intercept operations on persistent state in field access classes.  For 
+    property access classes, however, OpenJPA uses a different strategy.  OpenJPA 
+    generates dynamic subclasses of your persistent classes at runtime.  
+    These subclasses override your persistent property "getter" and 
+    "setter" methods to control the loading and dirtying of persistent
+    state.
+    </para>
+    <para>
+    Any time you look up an entity by id, merge an entity, or retrieve an
+    entity by query, OpenJPA returns an instance of the entity's 
+    dynamically-generated subclass.  When you persist new entities, 
+    however, you typically create them with the Java <literal>new</literal>
+    operator, then pass them to 
+    <ulink url="&ejb-javadoc-dir;/javax/persistence/EntityManager.html">
+    <methodname>EntityManager.persist</methodname></ulink>.  Obviously,
+    these entities are not subclassed.  We must therefore consider two
+    categories of restrictions on property access entities: general
+    restrictions that allow your class to be dynamically subclassed by OpenJPA,
+    and special restrictions on non-subclassed instances you have created 
+    with the <literal>new</literal> operator.
+    </para>
+    <section id="ref_guide_pc_prop_sub">
+      <title>General Restrictions</title>
+      <para>
+      <xref linkend="jpa_overview_pc"/> of the JPA Overview
+      covers the restrictions imposed on persistent classes by the
+      JPA specification.  In order for dynamic subclassing
+      to work properly, your property access entities and 
+      embeddable types must obey those restrictions, as well as the
+      following additions:
+      </para>
+      <orderedlist>
+        <listitem>
+          <para>
+          <emphasis role="bold">Use <literal>
+          instanceof</literal>.</emphasis>  Because OpenJPA will return
+          instances of dynamically-generated subclasses, comparisons
+          on <classname>Class</classname> objects may fail.  Use
+          the <literal>instanceof</literal> operator instead when
+          testing for specific persistent types.
+          </para>  
+        </listitem>
+        <listitem>
+          <para>
+          <emphasis role="bold">Define <literal>public</literal>
+          or <literal>protected</literal> methods.</emphasis>
+          OpenJPA's subclass must be able to override your persistent
+          property accessor and mutator methods. 
+          </para>  
+        </listitem>
+        <listitem>
+          <para>
+          <emphasis role="bold">Do not access persistent fields
+          directly.</emphasis>  The OpenJPA runtime relies on getter
+          and setter method invocations to detect state access.  
+          Thus, outside of your getter and setter methods themselves,
+          you should not manipulate persistent fields directly.  This 
+          restriction applies not only to access from outside
+          code, but also to access from within the business methods
+          of your entity class.  All manipulation of persistent
+          state must go through your getter and setter methods.  
+          </para>  
+        </listitem>
+      </orderedlist>
+    </section>
+    <section id="ref_guide_pc_prop_new">
+      <title>Restrictions on New Instances</title>
+      <para>
+      Non-subclassed property access objects do not afford OpenJPA any 
+      opportunities to intercept persistent state manipulation or store
+      additional bookkeeping information in the object itself.  This is
+      not normally problematic, but does limit the use of these
+      objects in an extended persistence context (see
+      <xref linkend="jpa_overview_emfactory_perscontext"/>).  
+      </para>
+      <itemizedlist>
+        <listitem>
+          <para>
+          New instances using OpenJPA's datastore identity feature
+          (see <xref linkend="ref_guide_pc_oid"/> below) that become
+          detached cannot be merged.  OpenJPA has no place to store the
+          datastore identity value in the non-subclassed detached 
+          instance, so the object's identity is lost.
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+          New instances without a 
+          <link linkend="jpa_overview_meta_version">version field
+          </link> must use a <link linkend="jpa_overview_meta_id">
+          <literal>generate</literal> strategy</link> other than
+          <literal>GeneratorType.NONE</literal> for at least one
+          primary key field to be merged after being detached.
+          Otherwise, OpenJPA has no criteria with which to differentiate
+          a detached object from a new one.
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+          OpenJPA typically detects attempts to read an auto-assigned 
+          field in a new instance.   OpenJPA generates the value or 
+          flushes to the database transparently on access.
+          OpenJPA cannot detect state reads in non-subclassed property 
+          access classes, however.  Thus, 
+          reading an auto-assigned property will return its 
+          Java default value until you flush or commit.
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+          If you continue using a property access object created with
+          <literal>new</literal> in subsequent transactions of an
+          extended persistence context, OpenJPA will not be able to
+          lazy-load its state.  On boundaries where OpenJPA would 
+          normally clear state (such as when entering a non-optimistic
+          transaction), OpenJPA will clear, then immediately re-load
+          all data.  Because OpenJPA cannot detect state manipulation
+          on a non-subclassed instance, this is the only way to ensure
+          that all properties have the correct values should you 
+          access them.
+          </para>
+        </listitem>
+      </itemizedlist>
+      <para>
+      If you find yourself running up against these limitations in 
+      practice, consider using field access, or taking advantage of the
+      <ulink url="&javadoc-dir;/openjpa/persistence/OpenJPAEntityManager.html">
+      <classname>OpenJPAEntityManager</classname></ulink>, OpenJPA's 
+      extended <classname>EntityManager</classname> interface:
+      </para>
+<programlisting>
+public &lt;T> T createInstance (Class&lt;T> cls);
+</programlisting>
+      <para>
+      The <classname>OpenJPAEntityManager</classname>'s
+      <literal>createInstance</literal> method acts as a factory for 
+      entity and embeddable types.
+      When the given class uses property access, it returns a generated
+      subclass instance.  This instance is not subject to the
+      limitations of objects created with <literal>new</literal>.
+      </para>
+    </section>
+  </section>
+  -->
+      <section id="ref_guide_pc_oid">
+        <title>Object Identity</title>
+        <indexterm zone="ref_guide_pc_oid">
+          <primary>identity</primary>
+        </indexterm>
+        <para>
+    The JPA specification requires you to declare one or more
+    identity fields in your persistent classes.  OpenJPA fully supports
+    this form of object identity, called <emphasis>application</emphasis>
+    identity.  OpenJPA, however, also supports <emphasis>datastore</emphasis>
+    identity.  In datastore identity, you do not declare any primary key
+    fields.  OpenJPA manages the identity of your persistent objects for
+    you through a surrogate key in the database. 
+    </para>
+        <para>
+    You can control how your JPA datastore identity value is generated
+    through OpenJPA's 
+    <ulink url="../apidocs/org/apache/openjpa/persistence/DataStoreId.html"><classname>org.apache.openjpa.persistence.DataStoreId</classname></ulink> class
+    annotation.  This annotation has <literal>strategy</literal> and
+    <literal>generator</literal> properties that mirror the same-named
+    properties on the standard <classname>javax.persistence.GeneratedValue
+    </classname> annotation described in 
+    <xref linkend="jpa_overview_meta_id"/> of the JPA Overview.
+    
+    </para>
+        <para>
+    To retrieve the identity value of a datastore identity entity, use the
+    <methodname>OpenJPAEntityManager.getObjectId (Object entity)
+    </methodname> method.  See 
+    <xref linkend="ref_guide_runtime_em"/>
+    for more information on the <classname>OpenJPAEntityManager</classname>.
+    </para>
+        <example id="ref_guide_pc_oid_datastoreentityex">
+          <title>JPA Datastore Identity Metadata</title>
+          <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+@Entity
+@DataStoreId
+public class LineItem
+{
+    ... no @Id fields declared ...
+}
+</programlisting>
+        </example>
+        <section id="ref_guide_pc_oid_datastore">
+          <title>Datastore Identity Objects</title>
+          <indexterm zone="ref_guide_pc_oid">
+            <primary>identity</primary>
+            <secondary>datastore</secondary>
+          </indexterm>
+          <para>
+      Internally, OpenJPA uses the public 
+      <ulink url="../apidocs/org/apache/openjpa/util/Id.html"><classname>org.apache.openjpa.util.Id
+      </classname></ulink> class for datastore identity objects.  When
+      writing OpenJPA plugins, you can manipulate datastore identity objects
+      by casting them to this class.  You can also create your own 
+      <classname>Id</classname> instances and pass them to any internal
+      OpenJPA method that expects an identity object.
+      </para>
+          <para>
+      In JPA, you will never see <classname>Id</classname> instances
+      directly.  Instead, calling <classname>OpenJPAEntityManager.getObjectId
+      </classname> on a datastore identity object will return the
+      <classname>Long</classname> surrogate primary key value for that
+      object.  You can then use this value in calls to 
+      <classname>EntityManager.find</classname> for subsequent lookups
+      of the same record.
+      </para>
+        </section>
+        <section id="ref_guide_pc_oid_application">
+          <title>Application Identity Tool</title>
+          <indexterm zone="ref_guide_pc_oid_application">
+            <primary>identity</primary>
+            <secondary>application</secondary>
+            <tertiary>application identity tool</tertiary>
+          </indexterm>
+          <indexterm zone="ref_guide_pc_oid_application">
+            <primary>application identity tool</primary>
+          </indexterm>
+          <para>
+      If you choose to use application identity, you may want to take
+      advantage of OpenJPA <phrase>JPA</phrase>'s application identity tool.
+      The application identity tool generates Java code implementing the
+      identity class for any persistent type using application 
+      identity.  The code satisfies all the requirements the specification
+      places on identity classes.  You can use it as-is, or simply use it
+      as a starting point, editing it to meet your needs.
+      </para>
+          <para>
+      Before you can run the application identity tool on a persistent
+      class, the class must be compiled and must have complete  
+      metadata.  All primary key fields must be marked as such in the
+      metadata.
+      </para>
+          <para>
+      In JPA metadata, do not attempt to specify the 
+      <literal>@IdClass</literal> annotation unless you are using the
+      application identity tool to overwrite an existing identity class.
+      Attempting to set the value of the <literal>@IdClass</literal> to 
+      a non-existent class will prevent your persistent class from 
+      compiling.  Instead, use the <literal>-name</literal> or
+      <literal>-suffix</literal> options described below to tell OpenJPA
+      what name to give your generated identity class.  Once the 
+      application identity tool has generated the class code, you can
+      set the <literal>@IdClass</literal> annotation.
+      </para>
+          <para>
+      The application identity tool can be invoked via the included 
+      <literal>appidtool</literal> shell/bat script or via its Java class,
+      <ulink url="../apidocs/org/apache/openjpa/enhance/ApplicationIdTool"><classname>org.apache.openjpa.enhance.ApplicationIdTool</classname></ulink>.  
+      </para>
+          <note>
+            <para><xref linkend="ref_guide_integration_appidtool"/> describes
+        the application identity tool's Ant task.
+        </para>
+          </note>
+          <example id="ref_guide_pc_appid_appidtool">
+            <title>Using the Application Identity Tool</title>
+            <programlisting format="linespecific">
+appidtool -s Id Magazine.java
+</programlisting>
+          </example>
+          <para>
+      The application identity tool accepts the standard set of 
+      command-line arguments defined by the configuration framework
+      (see <xref linkend="ref_guide_conf_devtools"/>),
+      including code formatting flags described in
+      <xref linkend="ref_guide_conf_devtools_format"/>.
+      It also accepts the following arguments:
+      </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>-directory/-d &lt;output directory&gt;</literal>: 
+          Path to the output directory.  If the directory does not 
+          match the generated oid class' package, the package 
+          structure will be created beneath the directory.  If not 
+          specified, the tool will first try to find the directory of
+          the <filename>.java</filename> file for the 
+          persistence-capable class, and failing that will use the 
+          current directory.
+          </para>
+            </listitem>
+            <listitem>
+              <para><literal>-ignoreErrors/-i &lt;true/t | false/f&gt;
+          </literal>:  If <literal>false</literal>, an exception will
+          be thrown if the tool is run on any class that does not 
+          use application identity, or is not the base class in the 
+          inheritance hierarchy (recall that subclasses never define 
+          the application identity class; they inherit it from their 
+          persistent superclass).
+          </para>
+            </listitem>
+            <listitem>
+              <para><literal>-token/-t &lt;token&gt;</literal>: The token
+          to use to separate stringified primary key values in the
+          string form of the object id.  This option is only used
+          if you have multiple primary key fields.  It defaults to
+          "::". 
+          </para>
+            </listitem>
+            <listitem>
+              <para><literal>-name/-n &lt;id class name&gt;</literal>: The name
+          of the identity class to generate.  If this option is 
+          specified, you must run the tool on exactly one class.
+          If the class metadata already names an object id class,
+          this option is ignored.  If the name is not fully qualified,
+          the persistent class' package is prepended to form the
+          qualified name.
+          </para>
+            </listitem>
+            <listitem>
+              <para><literal>-suffix/-s &lt;id class suffix&gt;</literal>: A
+          string to suffix each persistent class name with to form
+          the identity class name.  This option is overridden by
+          <literal>-name</literal> or by any object id class specified
+          in metadata.
+          </para>
+            </listitem>
+          </itemizedlist>
+          <para>
+      Each additional argument to the tool must be one of the following:
+      </para>
+          <itemizedlist>
+            <listitem>
+              <para>The full name of a persistent class.</para>
+            </listitem>
+            <listitem>
+              <para>The .java file for a persistent class.</para>
+            </listitem>
+            <listitem>
+              <para>
+          The <filename>.class</filename> file of a persistent class.
+          </para>
+            </listitem>
+          </itemizedlist>
+          <para>
+      If you do not supply any arguments to the tool, it will act on the
+      classes in your persistent classes list (see
+      <xref linkend="ref_guide_pc_pcclasses"/>).
+      </para>
+        </section>
+        <section id="ref_guide_pc_oid_pkgen_autoinc">
+          <title>Autoassign / Identity Strategy Caveats</title>
+          <indexterm zone="ref_guide_pc_oid_pkgen_autoinc">
+            <primary>datastore identity</primary>
+            <secondary>autoassign strategy</secondary>
+          </indexterm>
+          <indexterm zone="ref_guide_pc_oid_pkgen_autoinc">
+            <primary>datastore identity</primary>
+            <secondary>autoassign strategy</secondary>
+          </indexterm>
+          <indexterm zone="ref_guide_pc_oid_pkgen_autoinc">
+            <primary>persistent fields</primary>
+            <secondary>autoassign strategy</secondary>
+          </indexterm>
+          <para><xref linkend="jpa_overview_meta_gen"/> explains how to use JPA's
+      <literal>IDENTITY</literal> generation type to automatically assign
+      field values. However, here are some additional caveats you
+      should be aware of when using <literal>IDENTITY</literal> 
+      generation:
+      </para>
+          <orderedlist>
+            <listitem>
+              <para>
+          Your database must support auto-increment / identity
+          columns, or some equivalent (see 
+          <xref linkend="ref_guide_dbsetup_dbsupport_oracle"/> for
+          how to configure a combination of triggers and sequences to
+          fake auto-increment support in Oracle).
+          </para>
+            </listitem>
+            <listitem>
+              <para>
+          Auto-increment / identity columns must be an integer or 
+          long integer type.
+          </para>
+            </listitem>
+            <listitem>
+              <para>
+          Databases support auto-increment / identity columns
+          to varying degrees.  Some do not support them at all.
+          Others only allow a single such column per
+          table, and require that it be the primary key column.
+          More lenient databases may allow non-primary key 
+          auto-increment columns, and may allow more than one
+          per table.  See your database documentation for 
+          details.
+          </para>
+            </listitem>
+            <listitem>
+              <para>
+          Statements inserting into tables with auto-increment 
+          / identity columns cannot be batched.  After each insert, 
+          OpenJPA must go back to the database to retrieve the last 
+          inserted auto-increment value to set back in the
+          persistent object.  This can have a negative
+          impact on performance.
+          </para>
+            </listitem>
+          </orderedlist>
+        </section>
+      </section>
+      <section id="ref_guide_inverses">
+        <title>Managed Inverses</title>
+        <indexterm zone="ref_guide_inverses">
+          <primary>bidirectional relations</primary>
+          <secondary>automatic management</secondary>
+        </indexterm>
+        <para>
+    Bidirectional relations are an essential part of data modeling.
+    <xref linkend="jpa_overview_mapping"/> in the JPA Overview
+    explains how to use the <literal>mappedBy</literal> annotation attribute
+    to form bidirectional relations that also share datastore storage 
+    in JPA.  
+    </para>
+        <para>
+    OpenJPA also allows you to define purely logical bidirectional
+    relations.
+    <phrase>
+    The <ulink url="../apidocs/org/apache/openjpa/persistence/InverseLogical.html"><classname>org.apache.openjpa.persistence.InverseLogical</classname></ulink>
+    annotation names a logical inverse in JPA metadata.
+    </phrase>
+    
+    </para>
+        <example id="ref_guide_inverses_logicalex">
+          <title>Specifying Logical Inverses</title>
+          <para><literal>Magazine.coverPhoto</literal> and <literal>Photograph.mag
+      </literal> are each mapped to different foreign keys in their 
+      respective tables, but form a logical bidirectional relation.  Only
+      one of the fields needs to declare the other as its logical inverse,
+      though it is not an error to set the logical inverse of both fields.
+      </para>
+          <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+@Entity
+public class Magazine
+{
+    @OneToOne
+    private Photograph coverPhoto;
+    
+    ...
+}
+
+@Entity
+public class Photograph
+{
+    @OneToOne
+    @InverseLogical("coverPhoto")
+    private Magazine mag;
+    
+    ...
+}
+</programlisting>
+          <programlisting format="linespecific">
+&lt;class name="Magazine"&gt;
+    &lt;field name="coverPhoto"/&gt;
+    ...
+&lt;/class&gt;
+&lt;class name="Photograph"&gt;
+    &lt;field name="mag"&gt;
+        &lt;extension vendor-name="openjpa" key="inverse-logical" value="coverPhoto"/&gt;
+    &lt;/field&gt;
+    ...
+&lt;/class&gt;
+</programlisting>
+        </example>
+        <para>
+    Java does not provide any native facilities to ensure that both sides 
+    of a bidirectional relation remain consistent.  
+    Whenever you set one side of the relation, you must manually set the 
+    other side as well. 
+    </para>
+        <para>
+    By default, OpenJPA behaves the same way.  OpenJPA does not automatically 
+    propagate changes from one field in bidirectional relation to the other 
+    field.  This is in keeping with the philosophy of transparency, and 
+    also provides higher performance, as OpenJPA does not need to analyze 
+    your object graph to correct inconsistent relations.
+    </para>
+        <para><indexterm><primary>InverseManager</primary></indexterm>
+    If convenience is more important to you than strict transparency, 
+    however, you can enable inverse relation management in OpenJPA.
+    Set the <link linkend="openjpa.InverseManager"><classname>openjpa.InverseManager</classname></link> plugin property to 
+    <literal>true</literal> for standard management.  Under this setting,
+    OpenJPA detects changes to either side of a bidirectional relation (logical
+    or physical), and automatically sets the other side appropriately on 
+    flush.
+    </para>
+        <example id="ref_guide_inversesex">
+          <title>Enabling Managed Inverses</title>
+          <programlisting format="linespecific">
+&lt;property name="openjpa.InverseManager" value="true"/&gt;
+</programlisting>
+        </example>
+        <para>
+    The inverse manager has options to log a warning or throw an exception 
+    when it detects an inconsistent bidirectional relation, rather than
+    correcting it.  To use these modes, set the manager's <literal>Action
+    </literal> property to <literal>warn</literal> or 
+    <literal>exception</literal>, respectively.
+    </para>
+        <para>
+    By default, OpenJPA excludes <link linkend="ref_guide_pc_scos_proxy_lrs">
+    large result set fields</link> from management.  You can force
+    large result set fields to be included by setting the
+    <literal>ManageLRS</literal> plugin property to <literal>true</literal>.
+    </para>
+        <example id="ref_guide_inverses_logex">
+          <title>Log Inconsistencies</title>
+          <programlisting format="linespecific">
+&lt;property name="openjpa.InverseManager" value="true(Action=warn)"/&gt;
+</programlisting>
+        </example>
+      </section>
+      <section id="ref_guide_pc_scos">
+        <title>Persistent Fields</title>
+        <indexterm zone="ref_guide_pc_scos">
+          <primary>persistent fields</primary>
+        </indexterm>
+        <para>
+    OpenJPA enhances the specification's support for persistent 
+    fields in many ways.  This section documents aspects of OpenJPA's 
+    persistent field handling that may affect the way you design your 
+    persistent classes.  
+    </para>
+        <section id="ref_guide_pc_scos_restore">
+          <title>Restoring State</title>
+          <indexterm zone="ref_guide_pc_scos">
+            <primary>persistent fields</primary>
+            <secondary>field rollback</secondary>
+          </indexterm>
+          <indexterm zone="ref_guide_pc_scos_restore">
+            <primary>RestoreState</primary>
+          </indexterm>
+          <para>
+      While the JPA specification says that you should not use rolled 
+      back objects, such objects are perfectly valid in OpenJPA.  You can
+      control whether the objects' managed state is rolled back to its
+      pre-transaction values with the <link linkend="openjpa.RestoreState"><literal>openjpa.RestoreState</literal></link> configuration property.
+      <literal>none</literal> does not roll back state (the object
+      becomes hollow, and will re-load its state the next time it
+      is accessed), <literal>immutable</literal> restores immutable values
+      (primitives, primitive wrappers, strings) and clears mutable values
+      so that they are reloaded on next access, and <literal>all</literal>
+      restores all managed values to their pre-transaction state.
+      </para>
+        </section>
+        <section id="ref_guide_pc_scos_order">
+          <title>Typing and Ordering</title>
+          <indexterm zone="ref_guide_pc_scos_order">
+            <primary>persistent fields</primary>
+            <secondary>comparators</secondary>
+          </indexterm>
+          <para>
+      When loading data into a field, OpenJPA examines the value you assign 
+      the field in your declaration code or in your no-args constructor.
+      If the field value's type is more specific than the field's 
+      declared type, OpenJPA uses the value type to hold the loaded data.  
+      OpenJPA also uses the comparator you've initialized the field with, if
+      any.  Therefore, you can use custom comparators on your persistent 
+      field simply by setting up the comparator and using it in your 
+      field's initial value.
+      </para>
+          <example id="ref_guide_pc_scos_order_initialvals">
+            <title>Using Initial Field Values</title>
+            <para>
+        Though the annotations are left out for simplicity, assume
+        <literal>employeesBySal</literal> and 
+        <literal>departments</literal> are persistent fields in the
+        class below.
+        </para>
+            <programlisting format="linespecific">
+public class Company
+{
+    // OpenJPA will detect the custom comparator in the initial field value
+    // and use it whenever loading data from the database into this field
+    private Collection employeesBySal = new TreeSet (new SalaryComparator ());
+    private Map departments;
+
+    public Company
+    {
+        // or we can initialize fields in our no-args constructor; even though
+        // this field is declared type Map, OpenJPA will detect that it's actually
+        // a TreeMap and use natural ordering for loaded data
+        departments = new TreeMap ();
+    }
+
+    // rest of class definition...
+}
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_pc_calendar_timezone">
+          <title>Calendar Fields and TimeZones</title>
+          <indexterm zone="ref_guide_pc_calendar_timezone">
+            <primary>persistent fields</primary>
+            <secondary>calendar</secondary>
+          </indexterm>
+          <para>
+      OpenJPA's support for the <classname>java.util.Calendar</classname>
+      type will store only the <classname>Date</classname> part of the 
+      field, not the <classname>TimeZone</classname> associated with the
+      field. When loading the date into the <classname>Calendar
+      </classname> field, OpenJPA will use the <classname>TimeZone
+      </classname> that was used to initialize the field.
+      </para>
+          <note>
+            <para>
+        OpenJPA will automatically track changes made via modification
+        methods in fields of type
+        <classname>Calendar</classname>, with one exception:
+        when using Java version 1.3, the <methodname>set()</methodname>
+        method cannot be overridden, so when altering the calendar
+        using that method, the field must be explicitly marked
+        as dirty. This limitation does not apply when running with
+        Java version 1.4 and higer.
+        </para>
+          </note>
+        </section>
+        <section id="ref_guide_pc_scos_proxy">
+          <title>Proxies</title>
+          <indexterm zone="ref_guide_pc_scos_proxy">
+            <primary>proxies</primary>
+          </indexterm>
+          <indexterm>
+            <primary>persistent fields</primary>
+            <secondary>proxies</secondary>
+            <see>proxies</see>
+          </indexterm>
+          <para>
+      At runtime, the values of all mutable second class object fields 
+      in persistent and transactional objects are replaced with 
+      implementation-specific proxies.  On modification, these proxies 
+      notify their owning instance that they have been changed, so that 
+      the appropriate updates can be made on the datastore.
+      </para>
+          <section id="ref_guide_pc_scos_proxy_smart">
+            <title>Smart Proxies</title>
+            <indexterm zone="ref_guide_pc_scos_proxy_smart">
+              <primary>proxies</primary>
+              <secondary>smart</secondary>
+            </indexterm>
+            <para>
+        Most proxies only track whether or not they have been modified. 
+        Smart proxies for collection and map fields, however, keep a 
+        record of which elements have been added, removed, and changed.
+        This record enables the OpenJPA runtime to make more efficient
+        database updates on these fields. 
+        </para>
+            <para>
+        When designing your persistent classes, keep in mind that 
+        you can optimize for OpenJPA smart proxies by using fields of type 
+        <classname>java.util.Set</classname>, 
+        <classname>java.util.TreeSet</classname>, and 
+        <classname>java.util.HashSet</classname> for your collections 
+        whenever possible.  Smart proxies for these types are more 
+        efficient than proxies for <classname>List</classname>s.  You 
+        can also design your own smart proxies to further optimize OpenJPA
+        for your usage patterns.  See the section on 
+        <link linkend="ref_guide_pc_scos_proxy_custom">custom proxies
+        </link> for details.  
+        </para>
+          </section>
+          <section id="ref_guide_pc_scos_proxy_lrs">
+            <title>Large Result Set Proxies</title>
+            <indexterm zone="ref_guide_pc_scos_proxy_lrs">
+              <primary>proxies</primary>
+              <secondary>large result set</secondary>
+            </indexterm>
+            <indexterm zone="ref_guide_pc_scos_proxy_lrs">
+              <primary>large result sets</primary>
+              <secondary>fields</secondary>
+            </indexterm>
+            <para>
+        Under standard ORM behavior, traversing a persistent collection
+        or map field brings the entire contents of that field into
+        memory.  Some persistent fields, however, might represent
+        huge amounts of data, to the point that attempting to fully
+        instantiate them can overwhelm the JVM or seriously degrade
+        performance.
+        </para>
+            <para>
+        OpenJPA uses special proxy types to represent these "large result
+        set" fields.  OpenJPA's large result set proxies do not cache
+        any data in memory.  Instead, each operation on the proxy 
+        offloads the work to the database and returns the proper result.
+        For example, the <methodname>contains</methodname> method
+        of a large result set collection will perform a <literal>
+        SELECT COUNT(*)</literal> query with the proper <literal>WHERE
+        </literal> conditions to find out if the given element exists 
+        in the database's
+        record of the collection.  Similarly, each time you obtain
+        an iterator OpenJPA performs the proper query using the current
+        <link linkend="ref_guide_dbsetup_lrs">
+        large result set settings</link>, as discussed in the 
+        <link linkend="ref_guide_dbsetup">JDBC</link> chapter.  As you 
+        invoke <methodname>Iterator.next</methodname>, OpenJPA 
+        instantiates the result objects on-demand.
+        </para>
+            <para>
+        You can free the resources used by a large result set iterator 
+        by passing it to the static 
+        <link linkend="ref_guide_runtime_openjpapersistence"><methodname>OpenJPAPersistence.close</methodname></link> method. 
+        </para>
+            <example id="ref_guide_pc_scos_proxy_lrs_itr">
+              <title>Using a Large Result Set Iterator</title>
+              <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+Collection employees = company.getEmployees (); // employees is a lrs collection
+Iterator itr = employees.iterator ();
+while (itr.hasNext ())
+    process ((Employee) itr.next ());
+OpenJPAPersistence.close (itr);
+</programlisting>
+            </example>
+            <para>
+        You can also add and remove from large result set proxies, just
+        as with standard fields.  OpenJPA keeps a record of all changes
+        to the elements of the proxy, which it uses to make sure 
+        the proper results are always returned from collection and
+        map methods, and to update the field's database record on
+        commit.
+        </para>
+            <para>
+              <phrase>
+        In order to use large result set proxies in JPA, add the
+        <ulink url="../apidocs/org/apache/openjpa/persistence/LRS.html"><classname>
+        org.apache.openjpa.persistence.LRS</classname></ulink> annotation to the
+        persistent field.
+        </phrase>
+            </para>
+            <para>
+        The following restrictions apply to large result set fields:
+        </para>
+            <itemizedlist>
+              <listitem>
+                <para>
+            The field must be declared as either a 
+            <classname>java.util.Collection</classname> or 
+            <classname>java.util.Map</classname>.  It cannot be 
+            declared as any other type, including any sub-interface
+            of collection or map, or any concrete collection or map
+            class.
+            </para>
+              </listitem>
+              <listitem>
+                <para>
+            The field cannot have an externalizer
+            (see <xref linkend="ref_guide_pc_extern"/>).
+            </para>
+              </listitem>
+              <listitem>
+                <para>
+            Because they rely on their owning object for context, 
+            large result set proxies cannot be transferred from one
+            persistent field to another.  The following code would 
+            result in an error on commit:
+            </para>
+                <programlisting format="linespecific">
+Collection employees = company.getEmployees ()  // employees is a lrs collection
+company.setEmployees (null);
+anotherCompany.setEmployees (employees);
+</programlisting>
+              </listitem>
+            </itemizedlist>
+            <example id="ref_guide_pc_scos_proxy_lrs_extension">
+              <title>Marking a Large Result Set Field</title>
+              <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+@Entity
+public class Company
+{
+    @ManyToMany 
+    @LRS private Collection&lt;Employee&gt; employees;     
+
+    ...
+}
+</programlisting>
+            </example>
+          </section>
+          <section id="ref_guide_pc_scos_proxy_custom">
+            <title>Custom Proxies</title>
+            <indexterm zone="ref_guide_pc_scos_proxy_custom">
+              <primary>proxies</primary>
+              <secondary>custom</secondary>
+            </indexterm>
+            <indexterm zone="ref_guide_pc_scos_proxy_custom">
+              <primary>proxies</primary>
+              <secondary>ProxyManager</secondary>
+            </indexterm>
+            <para>
+        OpenJPA manages proxies through the
+        <ulink url="../apidocs/org/apache/openjpa/util/ProxyManager.html"><classname>org.apache.openjpa.util.ProxyManager</classname></ulink> interface.
+        OpenJPA includes a default proxy manager, the
+        <classname>org.apache.openjpa.util.ProxyManagerImpl</classname> (with a plugin
+        alias name of <literal>default</literal>),
+        that will meet the needs of most users.   The default proxy
+        manager understands the following configuration properties:
+        </para>
+            <itemizedlist>
+              <listitem>
+                <para><literal>TrackChanges</literal>: Whether to use 
+            <link linkend="ref_guide_pc_scos_proxy_smart">smart 
+            proxies</link>.  Defaults to <literal>true</literal>.
+            </para>
+              </listitem>
+            </itemizedlist>
+            <para>
+        For custom behavior, OpenJPA allows you to define your own 
+        proxy classes, and your own proxy manager.  See the 
+        <literal>openjpa.util</literal> package 
+        <ulink url="../apidocs/">Javadoc</ulink> for details on the 
+        interfaces involved, and the utility classes OpenJPA provides to 
+        assist you.
+        </para>
+            <para>
+        You can plug your custom proxy manager into the OpenJPA runtime
+        through the <link linkend="openjpa.ProxyManager"><literal>
+        openjpa.ProxyManager</literal></link> configuration property.  
+        
+        </para>
+            <example id="ref_guide_pc_scos_proxy_custom_ex">
+              <title>Configuring the Proxy Manager</title>
+              <programlisting format="linespecific">
+&lt;property name="openjpa.ProxyManager" value="TrackChanges=false"/&gt;
+</programlisting>
+            </example>
+          </section>
+        </section>
+        <section id="ref_guide_pc_extern">
+          <title>Externalization</title>
+          <indexterm zone="ref_guide_pc_extern">
+            <primary>externalization</primary>
+          </indexterm>
+          <indexterm>
+            <primary>persistent fields</primary>
+            <secondary>externalization</secondary>
+            <see>externalization</see>
+          </indexterm>
+          <para>
+      OpenJPA offers the ability to write
+      <link linkend="ref_guide_mapping_custom_field">custom field 
+      mappings</link> in order to have complete control over the 
+      mechanism with which fields are stored, queried, and loaded from 
+      the datastore. Often, however, a custom mapping is overkill.  
+      There is often a simple transformation from a Java field value
+      to its database representation.  Thus, OpenJPA provides the 
+      externalization service.  Externalization allows you to specify 
+      methods that will externalize a field value to its database 
+      equivalent on store and then rebuild the value from its 
+      externalized form on load.
+      </para>
+          <note>
+            <para>
+        Fields of embeddable classes used for <literal>@EmbeddedId
+        </literal> values in JPA cannot have externalizers. 
+        </para>
+          </note>
+          <para>
+      The 
+      <phrase>
+      JPA <ulink url="../apidocs/org/apache/openjpa/persistence/Externalizer.html"><classname>org.apache.openjpa.persistence.Externalizer</classname></ulink>
+      annotation
+      </phrase>
+      
+      
+      sets the name of a method that will be invoked to convert the field
+      into its external form for database storage. You can specify
+      either the name of a non-static method, which will be invoked on 
+      the field value, or a static method, which will be invoked with 
+      the field value as a parameter. Each method can also take an 
+      optional 
+      <ulink url="../apidocs/org/apache/openjpa/kernel/StoreContext.html"><classname>StoreContext</classname></ulink> parameter for 
+      access to a persistence context.  The return value of the method is
+      the field's external
+      form.  By default, OpenJPA assumes that all named methods belong to the
+      field value's class (or its superclasses).  You can, however, 
+      specify static methods of other classes using the format
+      <literal>&lt;class-name&gt;.&lt;method-name&gt;</literal>.
+      </para>
+          <para>
+      Given a field of type <classname>CustomType</classname> that 
+      externalizes to a string, the table below demonstrates several
+      possible externalizer methods and their corresponding
+      metadata extensions.
+      </para>
+          <table tocentry="1">
+            <title>Externalizer Options</title>
+            <tgroup cols="2" align="left" colsep="1" rowsep="1">
+              <colspec colname="method"/>
+              <colspec colname="extension"/>
+              <thead>
+                <row>
+                  <entry colname="method">Method</entry>
+                  <entry colname="extension">Extension</entry>
+                </row>
+              </thead>
+              <tbody>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public String CustomType.toString()
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+                    <literal>
+              @Externalizer("toString")
+              </literal>
+                  </entry>
+                </row>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public String CustomType.toString(StoreContext ctx)
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+                    <literal>
+              @Externalizer("toString")
+              </literal>
+                  </entry>
+                </row>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public static String AnyClass.toString(CustomType ct)
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+                    <literal>
+              @Externalizer("AnyClass.toString")
+              </literal>
+                  </entry>
+                </row>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public static String AnyClass.toString(CustomType ct, StoreContext ctx)
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+                    <literal>
+              @Externalizer("AnyClass.toString")
+              </literal>
+                  </entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </table>
+          <para>
+      The 
+      <phrase>
+      JPA <ulink url="../apidocs/org/apache/openjpa/persistence/Factory.html"><classname>org.apache.openjpa.persistence.Factory</classname></ulink> annotation
+      </phrase>
+      
+      
+      contains the name of a method that will be invoked to 
+      instantiate the field from the external form stored in 
+      the database. Specify a static method name.  The method will
+      will be invoked with the externalized value and must return 
+      an instance of the field type. The method can also take an optional
+      <ulink url="../apidocs/org/apache/openjpa/kernel/StoreContext.html"><classname>StoreContext</classname></ulink> parameter for 
+      access to a persistence context.
+      If a factory is not specified, OpenJPA will use the constructor 
+      of the field type that takes a single argument of the external 
+      type, or will throw an exception if no constructor with that 
+      signature exists.
+      </para>
+          <para>
+      Given a field of type <classname>CustomType</classname> that 
+      externalizes to a string, the table below demonstrates several
+      possible factory methods and their corresponding
+      metadata extensions.
+      </para>
+          <table tocentry="1">
+            <title>Factory Options</title>
+            <tgroup cols="2" align="left" colsep="1" rowsep="1">
+              <colspec colname="method"/>
+              <colspec colname="extension"/>
+              <thead>
+                <row>
+                  <entry colname="method">Method</entry>
+                  <entry colname="extension">Extension</entry>
+                </row>
+              </thead>
+              <tbody>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public CustomType(String str)
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+              none
+              </entry>
+                </row>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public static CustomType CustomType.fromString(String str)
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+                    <literal>
+              @Factory("fromString")
+              </literal>
+                  </entry>
+                </row>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public static CustomType CustomType.fromString(String str, StoreContext ctx)
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+                    <literal>
+              @Factory("fromString")
+              </literal>
+                  </entry>
+                </row>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public static CustomType AnyClass.fromString(String str)
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+                    <literal>
+              @Factory("AnyClass.fromString")
+              </literal>
+                  </entry>
+                </row>
+                <row>
+                  <entry colname="method">
+                    <literal>
+              public static CustomType AnyClass.fromString(String str, StoreContext ctx)
+              </literal>
+                  </entry>
+                  <entry colname="extension">
+                    <literal>
+              @Factory("AnyClass.fromString")
+              </literal>
+                  </entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </table>
+          <para>
+      If your externalized field is not a standard persistent type, you
+      must explicitly mark it persistent.
+      <phrase>
+      In JPA, you can force a persistent field by annotating it with 
+      <link linkend="ref_guide_meta_jpa_persistent"><classname>
+      org.apache.openjpa.persistence.Persistent</classname></link> annotation.
+      </phrase>
+      
+      </para>
+          <note>
+            <para>
+        If your custom field type is mutable and is not a standard
+        collection, map, or date class, OpenJPA will not be able to
+        detect changes to the field.  You must mark the field dirty
+        manully, or create a custom field proxy.
+        </para>
+            <para>
+              <phrase>
+        See <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><methodname>OpenJPAEntityManager.dirty</methodname></ulink> for how
+        to mark a field dirty manually in JPA.
+        </phrase>
+            </para>
+            <para>
+        See <xref linkend="ref_guide_pc_scos_proxy"/> for a discussion 
+        of proxies.
+        
+        </para>
+          </note>
+          <para>
+      You can externalize a field to virtually any value that is 
+      supported by OpenJPA's field mappings (embedded relations are the
+      exception; you must declare your field to be a persistence-capable 
+      type in order to embed it).  This means that
+      a field can externalize to something as simple as a primitive, 
+      something as complex as a collection or map of 
+      persistence-capable objects, or anything in between.  If you do 
+      choose to externalize to a collection or map, OpenJPA recognizes a 
+      family of metadata extensions for specying type information
+      for the externalized form of your fields - see 
+      <xref linkend="type"/>.  If the external form of your field 
+      is a persistence-capable object, or contains persistence-capable 
+      objects, OpenJPA will correctly include the objects in its 
+      persistence-by-reachability algorithms and its delete-dependent 
+      algorithms.
+      </para>
+          <para>
+      The example below demonstrates a few forms of externalization.
+      
+      </para>
+          <example id="ref_guide_pc_externex">
+            <title>Using Externalization</title>
+            <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+@Entity
+public class Magazine
+{
+    // use Class.getName and Class.forName to go to/from strings
+    @Persistent
+    @Externalizer("getName") 
+    @Factory("forName")
+    private Class cls;
+
+    // use URL.getExternalForm for externalization. no factory; 
+    // we can rely on the URL string constructor
+    @Persistent
+    @Externalizer("toExternalForm")
+    private URL url;
+
+    // use our custom methods; notice how we use the KeyType and ElementType 
+    // annotations to specify the metadata for our externalized map
+    @Persistent 
+    @Externalizer("Magazine.mapFromCustomType")
+    @Factory("Magazine.mapToCustomType")
+    @KeyType(String.class) @ElementType(String.class)
+    private CustomType customType;
+
+    public static Map mapFromCustomType (CustomType customType)
+    {
+        ... logic to pack custom type into a map ...
+    }
+
+    public static CustomType mapToCustomType (Map map)
+    {
+        ... logic to create custom type from a map ...
+    }
+
+    ...
+}
+</programlisting>
+          </example>
+          <para><indexterm><primary>externalization</primary><secondary>queries</secondary></indexterm>
+      You can query externalized fields using parameters.
+      Pass in a value of the field type when executing the query.  OpenJPA 
+      will externalize the parameter using the externalizer method named 
+      in your metadata, and compare the externalized parameter with the 
+      value stored in the database.   As a shortcut, OpenJPA 
+      also allows you to use parameters or literals of the field's 
+      externalized type in queries, as demonstrated in the example below.
+      </para>
+          <note>
+            <para>
+        Currently, queries are limited 
+        to fields that externalize to a primitive, primitive wrapper,
+        string, or date types, due to constraints on query syntax.  
+        </para>
+          </note>
+          <example id="ref_guide_pc_extern_queryex">
+            <title>Querying Externalization Fields</title>
+            <para>
+        Assume the <classname>Magazine</classname> class has the
+        same fields as in the previous example.
+        </para>
+            <programlisting format="linespecific">
+// you can query using parameters
+Query q = em.createQuery ("select m from Magazine m where m.url = :u");
+q.setParameter ("u", new URL ("http://www.solarmetric.com"));
+List results = q.getResultList ();
+
+// or as a shortcut, you can use the externalized form directly
+q = em.createQuery ("select m from Magazine m where m.url = 'http://www.solarmetric.com'");
+results = q.getResultList ();
+</programlisting>
+          </example>
+          <section id="ref_guide_pc_extern_values">
+            <title>External Values</title>
+            <indexterm zone="ref_guide_pc_extern_values">
+              <primary>externalization</primary>
+              <secondary>external values</secondary>
+            </indexterm>
+            <para>
+        Externalization often takes simple constant values and
+        transforms them to constant values of a different type.
+        An example would be storing a <classname>boolean</classname> 
+        field as a <classname>char</classname>, where <literal>true
+        </literal> and <literal>false</literal> would be stored
+        in the database as <literal>'T'</literal> and 
+        <literal>'F'</literal> respectively.
+        </para>
+            <para>
+        OpenJPA allows you to define these simple translations in 
+        metadata, so that the field behaves as in
+        <link linkend="ref_guide_pc_extern">full-fledged 
+        externalization</link> without requiring 
+        externalizer and factory methods.  External values supports
+        translation of pre-defined simple types 
+        (primitives, primitive wrappers, and Strings), to other
+        pre-defined simple values.
+        </para>
+            <para>
+        Use the
+        <phrase>
+        JPA 
+        <ulink url="../apidocs/org/apache/openjpa/persistence/ExternalValues.html"><classname>org.apache.openjpa.persistence.ExternalValues</classname></ulink>
+        annotation
+        </phrase>
+        
+        
+        to define external value translations.  The 
+        values are defined in a format similar to that of 
+        <link linkend="ref_guide_conf_plugins">configuration
+        plugins</link>, except that the value pairs represent Java and 
+        datastore values.  To convert the Java boolean
+        values of <literal>true</literal> and <literal>false</literal>
+        to the character values <literal>T</literal> and <literal>F
+        </literal>, for example, you would use the extension value: 
+        <literal>true=T,false=F</literal>.
+        </para>
+            <para>
+        If the type of the datastore value is different from 
+        the field's type, use the 
+        <phrase>
+        JPA <ulink url="../apidocs/org/apache/openjpa/persistence/Type.html"><classname>org.apache.openjpa.persistence.Type</classname></ulink> annotation
+        </phrase>
+        
+        
+        to define the datastore type.
+        </para>
+            <example id="externvalues_ex">
+              <title>Using External Values</title>
+              <para>
+          This example uses external value translation to transform
+          a string field to an integer in the database.
+          </para>
+              <programlisting format="linespecific">
+public class Magazine
+{
+    @ExternalValues({"SMALL=5", "MEDIUM=8", "LARGE=10"})
+    @Type(int.class)
+    private String sizeWidth;
+
+    ...
+}
+</programlisting>
+            </example>
+          </section>
+        </section>
+      </section>
+      <section id="ref_guide_fetch">
+        <title>Fetch Groups</title>
+        <indexterm zone="ref_guide_fetch">
+          <primary>fetch groups</primary>
+        </indexterm>
+        <para>
+  Fetch groups are sets of fields that load together.  They can be used to
+  to pool together associated fields in order to provide performance 
+  improvements over standard data fetching.  Specifying fetch groups allows 
+  for tuning of lazy loading and eager fetching behavior.
+  </para>
+        <para>
+  The JPA Overview's <xref linkend="jpa_overview_meta_fetch"/> 
+  describes how to use JPA metadata annotations to control whether a field is
+  fetched eagerly or lazily.  Fetch groups add a dynamic aspect to this 
+  standard ability.  As you will see, OpenJPA's JPA extensions allow you can add
+  and remove fetch groups at runtime to vary the sets of fields that are 
+  eagerly loaded.
+  </para>
+        <section id="ref_guide_fetch_custom">
+          <title>Custom Fetch Groups</title>
+          <para>
+    OpenJPA places any field that is eagerly loaded according to the JPA 
+    metadata rules into the built-in <emphasis>default
+    </emphasis> fetch group.  The default fetch group is always active; 
+    you cannot remove it at runtime.  Thus fields in this group are
+    always loaded immediately when an object is fetched from the datastore.
+    </para>
+          <para>
+    A field can be a member of zero or one fetch groups, including the 
+    default fetch group. That is, fields in the default fetch group cannot 
+    be in an additional fetch group, and a field cannot declare itself a 
+    member of more than one fetch group.  So to place a field in a custom
+    fetch group, you must first exclude it from eager fetching in your
+    JPA metadata, if it does not already default to lazy loading.
+    </para>
+          <para>
+    When lazy-loading a field, OpenJPA checks to see 
+    if that field declares itself to be a member of a fetch group. If so, 
+    OpenJPA will load all fields in that fetch group.
+    </para>
+          <para>
+    Additionally, it is possible to configure a OpenJPA <classname>
+    EntityManager</classname> or <classname>Query</classname> to use a 
+    particular fetch group or set of fetch groups
+    when loading new objects, as described later in this chapter.
+    When this is the case, OpenJPA loads the default fetch group plus any 
+    fields in the specified set of additional fetch groups.
+    </para>
+          <para>
+    You create fetch groups with the 
+    <ulink url="../apidocs/org/apache/openjpa/persistence/FetchGroup.html"><classname>org.apache.openjpa.persistence.FetchGroup</classname></ulink> annotation.
+    If your class only has one custom fetch group, you can place this 
+    annotation directly on the class declaration.  Otherwise, use the 
+    <ulink url="../apidocs/org/apache/openjpa/persistence/FetchGroups.html"><classname>org.apache.openjpa.persistence.FetchGroups</classname></ulink> annotation 
+    to declare an array of individual <classname>FetchGroup</classname> 
+    values.  The <classname>FetchGroup</classname> annotation has the 
+    following properties:
+    </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>String name</literal>: The name of the fetch group.  
+        Fetch group names are global, and are expected to be shared 
+        among classes.  For example, a shopping website may use a 
+        <emphasis>detail</emphasis> fetch group in each product class 
+        to efficiently load all the data needed to display a product's
+        "detail" page.  The website might also define a 
+        sparse <emphasis>list</emphasis> fetch group containing only 
+        the fields needed to display a table of products, as in a search
+        result.
+        </para>
+              <para>
+        The following names are reserved for use by OpenJPA:
+        <literal>default</literal>, <literal>values</literal>, 
+        <literal>all</literal>, <literal>none</literal>, and any name
+        beginning with <literal>jdo</literal>, <literal>ejb</literal>,
+        or <literal>openjpa</literal>.
+        </para>
+            </listitem>
+<!--
+      <listitem>
+        <para>
+        <literal>String[] fetchGroups</literal>: Other fetch groups 
+        whose fields to include in this group.
+        </para>
+      </listitem>
+      -->
+            <listitem>
+              <para><literal>FetchAttribute[] attributes</literal>: The set of
+        persistent fields or properties in the fetch group.
+        </para>
+            </listitem>
+          </itemizedlist>
+          <para>
+    As you might expect, listing a 
+    <ulink url="../apidocs/org/apache/openjpa/persistence/FetchAttribute.html"><classname>org.apache.openjpa.persistence.FetchAttribute</classname></ulink>
+    within a <classname>FetchGroup</classname> includes the corresponding
+    persistent field or property in the fetch group.  Each <classname>
+    FetchAttribute</classname> has the following properties:
+    </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>String name</literal>: The name of the persistent 
+        field or property to include in the fetch group.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>depth</literal>: If the attribute represents a 
+        relation, the depth to which to recurse.  The current fetch 
+        group will be applied to the related object when fetching it,
+        and so on until the depth is exhausted or the related object has
+        no relations in the current fetch group.  Under the 
+        default depth of 1, the related object will be fetched, but none
+        of its relations will be traversed, even if they are in
+        the current fetch group.  With a depth of 2, the related object 
+        will be fetched, and if it has any relations in the 
+        current fetch group, those will be fetched with a depth of 1.
+        A depth of 0 indicates that the recursion continues until the
+        graph is exhausted or a related object has no relations
+        in the current fetch group.
+        </para>
+            </listitem>
+          </itemizedlist>
+          <para>
+    Thus, to create a <emphasis>detail</emphasis> fetch group consisting of
+    the <literal>publisher</literal> and <literal>articles</literal> 
+    relations, with the fetch group applied recursively to the related 
+    objects, use:
+    </para>
+          <example id="ref_guide_fetch_customgroups">
+            <title>Custom Fetch Group Metadata</title>
+            <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+@Entity
+@FetchGroups({
+    @FetchGroup(name="detail", attributes={
+        @FetchAttribute(name="publisher" depth=0),
+        @FetchAttribute(name="articles" depth=0)
+    }),
+    ...
+})
+public class Magazine
+{
+   ...
+}
+</programlisting>
+          </example>
+          <note>
+            <para>
+      OpenJPA currently only supports a depth of 0 for fetch attributes.
+      This restriction will be lifted in a future release, along with the
+      restriction limiting each attribute to a single fetch group.
+      </para>
+          </note>
+        </section>
+        <section id="ref_guide_fetch_conf">
+          <title>Custom Fetch Group Configuration</title>
+          <indexterm zone="ref_guide_fetch_conf">
+            <primary>fetch groups</primary>
+            <secondary>custom configuration</secondary>
+          </indexterm>
+          <para><indexterm><primary>fetch groups</primary><secondary>FetchGroups</secondary></indexterm>
+    You can control the default set of fetch groups with the
+    <link linkend="openjpa.FetchGroups"><literal>openjpa.FetchGroups</literal></link> configuration property.  Set this property to a comma-separated
+    list of fetch group names.
+    </para>
+          <para>
+    In JPA, OpenJPA's <classname>OpenJPAEntityManager</classname> and 
+    <classname>OpenJPAQuery</classname> extensions to the standard 
+    <classname>EntityManager</classname> and <classname>Query</classname>
+    interfaces provide access to a 
+    <ulink url="../../api/openjpa/persistence/FetchPlan.html"><classname>org.apache.openjpa.persistence.FetchPlan</classname></ulink> 
+    object.  The <classname>FetchPlan</classname>  
+    maintains the set of active fetch groups.  It begins with the 
+    groups defined in the <literal>openjpa.FetchGroups</literal> property,
+    but allows you to add and remove groups for an individual 
+    <classname>EntityManager</classname> or <classname>Query</classname> 
+    through the methods below.
+    </para>
+          <programlisting format="linespecific">
+public FetchPlan addFetchGroup (String group);
+public FetchPlan addFetchGroups (String... groups);
+public FetchPlan addFetchGroups (Collection groups);
+public FetchPlan removeFetchGroup (String group);
+public FetchPlan removeFetchGroups (String... groups);
+public FetchPlan removeFetchGroups (Collection groups);
+public FetchPlan resetFetchGroups ();
+public Collection&lt;String&gt; getFetchGroups (); 
+public void clearFetchGroups ();
+</programlisting>
+          <para><xref linkend="ref_guide_runtime"/> details the <classname>
+    OpenJPAEntityManager</classname>, <classname>OpenJPAQuery</classname>, and
+    <classname>FetchPlan</classname> interfaces.
+    </para>
+          <example id="ref_guide_fetch_conf_query">
+            <title>Using the FetchPlan</title>
+            <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAQuery kq = OpenJPAPersistence.cast (em.createQuery (...));
+kq.getFetchPlan ().addFetchGroup ("detail");
+List results = kq.getResultList ();
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_fetch_single_field">
+          <title>Per-field Fetch Configuration</title>
+          <indexterm zone="ref_guide_fetch_single_field">
+            <primary>fetch groups</primary>
+            <secondary>single fields</secondary>
+          </indexterm>
+          <para>
+    In addition to controlling fetch configuration on a
+    per-fetch-group basis, you can configure OpenJPA to include 
+    particular fields in the current fetch configuration. This
+    allows you to add individual fields that are not in the default
+    fetch group or in any other currently-active fetch groups to the
+    set of fields that will be eagerly loaded from the
+    database. 
+    </para>
+          <para>
+    JPA <classname>FetchPlan</classname> methods:
+    </para>
+          <programlisting format="linespecific">
+public FetchPlan addField (String field);
+public FetchPlan addFields (String... fields);
+public FetchPlan addFields (Class cls, String... fields);
+public FetchPlan addFields (Collection fields);
+public FetchPlan addFields (Class cls, Collection fields);
+public FetchPlan removeField (String field);
+public FetchPlan removeFields (String... fields);
+public FetchPlan removeFields (Class cls, String... fields);
+public FetchPlan removeFields (Collection fields);
+public FetchPlan removeFields (Class cls, Collection fields);
+public Collection&lt;String&gt; getFields (); 
+public void clearFields ();
+</programlisting>
+          <para>
+    The methods that take only string arguments use the fully-qualified 
+    field name, such as <literal>org.mag.Magazine.publisher</literal>.  
+    Similarly, <methodname>getFields</methodname> returns the set of 
+    fully-qualified field names.  In all methods, the named field
+    must be defined in the class specified in the invocation, not a 
+    superclass.  So, if the field <literal>publisher</literal> is
+    defined in base class <classname>Publication</classname> rather than
+    subclass <classname>Magazine</classname>, you must
+    invoke <literal>addField (Publication.class, "publisher")</literal>
+    and not <literal>addField (Magazine.class, "publisher")</literal>. 
+    This is stricter than Java's default field-masking algorithms, which 
+    would allow the latter method behavior if <literal>Magazine</literal> 
+    did not also define a field called <literal>publisher</literal>.
+    </para>
+          <para>
+    In order to avoid the cost of reflection, OpenJPA does not perform
+    any validation of the field name / class name pairs that you put
+    into the fetch configuration. If you specify non-existent class /
+    field pairs, nothing adverse will happen, but you will receive
+    no notification of the fact that the specified configuration is
+    not being used.
+    </para>
+          <example id="ref_guide_fetch-conf_per_field">
+            <title>Adding an Eager Field</title>
+            <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+kem.getFetchPlan ().addField (Magazine.class, "publisher");
+Magazine mag = em.find (Magazine.class, magId);
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_fetch_impl">
+          <title>Implementation Notes</title>
+          <itemizedlist>
+            <listitem>
+              <para>
+        Even when a direct relation is not eagerly fetched, OpenJPA 
+        selects the foreign key columns and caches the values.  This
+        way when you do traverse the relation, OpenJPA can often find the
+        related object in its cache, or at least avoid joins when 
+        loading the related object from the database.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        The above implicit foreign key-selecting behavior does not 
+        always apply when the relation is in a subclass table.  If the
+        subclass table would not otherwise be joined into the select,
+        OpenJPA avoids the extra join just to select the foreign key 
+        values.
+        </para>
+            </listitem>
+          </itemizedlist>
+        </section>
+      </section>
+      <section id="ref_guide_perfpack_eager">
+        <title>Eager Fetching</title>
+        <indexterm zone="ref_guide_perfpack_eager">
+          <primary>eager fetching</primary>
+        </indexterm>
+        <indexterm>
+          <primary>persistent fields</primary>
+          <see>eager fetching</see>
+        </indexterm>
+        <indexterm zone="ref_guide_perfpack_eager">
+          <primary>fetch groups</primary>
+          <secondary>eager fetching</secondary>
+          <seealso>eager fetching</seealso>
+        </indexterm>
+        <indexterm>
+          <primary>lazy loading</primary>
+          <seealso>eager fetching</seealso>
+          <seealso>fetch groups</seealso>
+        </indexterm>
+        <para>
+    Eager fetching is the ability to efficiently load subclass data and 
+    related objects along with the base instances being queried.  
+    Typically, OpenJPA has to make a trip to the database whenever a 
+    relation is loaded, or when you first access data that is mapped to a 
+    table other than the least-derived superclass table.  If you perform a 
+    query that returns 100 <classname>Person</classname> objects, and then 
+    you have to retrieve the <classname>Address</classname> for each 
+    person, OpenJPA may make as many as 101 queries (the initial 
+    query, plus one for the address of each person returned).  Or if some
+    of the <classname>Person</classname> instances turn out to be 
+    <classname>Employee</classname>s, where <classname>Employee</classname>
+    has additional data in its own joined table, OpenJPA once again might need
+    to make extra database trips to access the additional employee data.
+    With eager fetching, OpenJPA can reduce these cases to a single query.
+    </para>
+        
+        <para>
+    Eager fetching only affects relations in the fetch groups being loaded
+    (see <xref linkend="ref_guide_fetch"/>).  In
+    other words, relations that would not normally be loaded immediately
+    when retrieving an object or accessing a field are not affected by
+    eager fetching.  In our example above, the address of each person would
+    only be eagerly fetched if the query were configured to include the 
+    address field or its fetch group, or if the address were in the default
+    fetch group.  This allows you to control exactly which fields are 
+    eagerly fetched in different situations.  Similarly, queries that 
+    exclude subclasses aren't affected by eager subclass fetching, 
+    described below.
+    </para>
+        <para>
+    Eager fetching has three modes:
+    </para>
+        <itemizedlist>
+          <listitem>
+            <para><literal>none</literal>: No eager fetching is performed.
+        Related objects are always loaded in an independent select 

[... 504 lines stripped ...]


Mime
View raw message