openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mprud...@apache.org
Subject svn commit: r433761 [17/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_runtime.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml Tue Aug 22 14:28:53 2006
@@ -0,0 +1,1441 @@
+
+    <chapter id="ref_guide_runtime">
+      <title>Runtime Extensions</title>
+      <para>
+  This chapter describes OpenJPA extensions to the standard 
+  <phrase>JPA</phrase>
+  
+  
+  interfaces, and outlines some additional features of the OpenJPA runtime.
+  </para>
+      <section id="ref_guide_runtime_arch">
+        <title>Architecture</title>
+        <para>
+    Internally, OpenJPA does not adhere to any persistence specification.  The
+    OpenJPA kernel has its own set of APIs and components.  Specifications like
+    JPA and JDO are simply different "personalities" that can
+    OpenJPA's native kernel can adopt.
+    </para>
+        <para>
+    As a OpenJPA <phrase>JPA</phrase> user, you will not normally see beneath OpenJPA's
+    JPA personality.  OpenJPA allows you to access its feature set
+    without leaving the comfort of JPA.  Where OpenJPA goes beyond standard 
+    JPA functionality, we have crafted JPA-specific APIs to 
+    each OpenJPA extension for as seamless an experience as possible.
+    </para>
+        <para>
+    When writing OpenJPA plugins or otherwise extending the OpenJPA runtime, 
+    however, you will use OpenJPA's native APIs.  So that you won't feel lost,
+    the list below associates each specification interface with 
+    its backing native OpenJPA component:
+    </para>
+        <itemizedlist>
+          <listitem>
+            <para><classname>javax.persistence.EntityManagerFactory</classname>:
+        <emphasis><classname>org.apache.openjpa.kernel.BrokerFactory</classname></emphasis></para>
+          </listitem>
+          <listitem>
+            <para><classname>javax.persistence.EntityManager</classname>:
+        <emphasis><classname>org.apache.openjpa.kernel.Broker</classname></emphasis></para>
+          </listitem>
+          <listitem>
+            <para><classname>javax.persistence.Query</classname>:
+        <emphasis><classname>org.apache.openjpa.kernel.Query</classname></emphasis></para>
+          </listitem>
+          <listitem>
+            <para><classname>org.apache.openjpa.persistence.Extent</classname>:
+        <emphasis><classname>org.apache.openjpa.kernel.Extent</classname></emphasis></para>
+          </listitem>
+          <listitem>
+            <para><classname>org.apache.openjpa.persistence.StoreCache</classname>:
+        <emphasis><classname>org.apache.openjpa.datacache.DataCache</classname></emphasis></para>
+          </listitem>
+          <listitem>
+            <para><classname>org.apache.openjpa.persistence.QueryResultCache</classname>:
+        <emphasis><classname>org.apache.openjpa.datacache.QueryCache</classname></emphasis></para>
+          </listitem>
+          <listitem>
+            <para><classname>org.apache.openjpa.persistence.FetchPlan</classname>:
+        <emphasis><classname>org.apache.openjpa.kernel.FetchConfiguration</classname></emphasis></para>
+          </listitem>
+          <listitem>
+            <para><classname>org.apache.openjpa.persistence.Generator</classname>:
+        <emphasis><classname>org.apache.openjpa.kernel.Seq</classname></emphasis></para>
+          </listitem>
+        </itemizedlist>
+        <para>
+    The <link linkend="ref_guide_runtime_openjpapersistence"><classname>
+    org.apache.openjpa.persistence.OpenJPAPersistence</classname></link> helper allows you 
+    to convert between <classname>EntityManagerFactories</classname> and
+    <classname>BrokerFactories</classname>, 
+    <classname>EntityManager</classname>s and
+    <classname>Broker</classname>s. 
+    </para>
+        <section id="ref_guide_runtime_pmextension">
+          <title>Broker Customization</title>
+          <indexterm zone="ref_guide_runtime_pmextension">
+            <primary>OpenJPAEntityManager</primary>
+            <secondary>extending</secondary>
+          </indexterm>
+          <para>
+      Some advanced users may want to add capabilities to OpenJPA's internal
+      <ulink url="../apidocs/org/apache/openjpa/kernel/BrokerImpl.html"><classname>org.apache.openjpa.kernel.BrokerImpl</classname></ulink>.
+      You can configure OpenJPA to use a custom subclass of
+      <classname>BrokerImpl</classname> through the 
+      <link linkend="openjpa.BrokerImpl"><literal>openjpa.BrokerImpl</literal></link> configuration property.  Set this property to the full 
+      class name of your custom subclass.
+      </para>
+          <para>
+      As a <link linkend="ref_guide_conf_plugins">plugin string</link>, 
+      you can also use this property to configure the <classname>
+      BrokerImpl</classname> with the following properties:
+      </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>EvictFromDataCache</literal>: When evicting an
+          object through the <methodname>OpenJPAEntityManager.evict
+          </methodname> methods, whether to also evict it from the 
+          OpenJPA's <link linkend="ref_guide_cache">data cache</link>.
+          Defaults to <literal>false</literal>.
+          </para>
+            </listitem>
+          </itemizedlist>
+          <example id="ref_guide_runtime_pm_evictex">
+            <title>Evict from Data Cache</title>
+            <programlisting format="linespecific">
+&lt;property name="openjpa.BrokerImpl" value="EvictFromDataCache=true"/&gt;
+</programlisting>
+          </example>
+        </section>
+      </section>
+      <section id="ref_guide_runtime_ejb">
+        <title>JPA Extensions</title>
+        <para>
+    The following sections outline the runtime interfaces you can use
+    to access OpenJPA-specific functionality from JPA.  Each 
+    interface contains services and convenience methods missing from the 
+    JPA specification.  OpenJPA strives to use the same naming 
+    conventions and API patterns as standard JPA methods in all
+    extensions, so that OpenJPA JDO APIs feel as much as possible like 
+    standard JPA.
+    </para>
+        <para>
+    You may have noticed the examples throughout this document using the
+    <methodname>OpenJPAPersistence.cast</methodname> methods to cast from
+    standard JPA interfaces to OpenJPA extended interfaces. 
+    This is the recommended practice.  Some application server vendors
+    may proxy OpenJPA's JPA implementation, preventing a straight
+    cast.  <classname>OpenJPAPersistence</classname>'s <methodname>cast
+    </methodname> methods work around these proxies.
+    </para>
+        <programlisting format="linespecific"> 
+public static OpenJPAEntityManagerFactory cast (EntityManagerFactory emf);
+public static OpenJPAEntityManager cast (EntityManager em);
+public static OpenJPAQuery cast (Query q);
+</programlisting>
+        <para>
+    We provide additional information on the <classname>OpenJPAPersistence
+    </classname> helper <link linkend="ref_guide_runtime_openjpapersistence">
+    below</link>.
+    </para>
+        <section id="ref_guide_runtime_emfactory">
+          <title>OpenJPAEntityManagerFactory</title>
+          <indexterm zone="ref_guide_runtime_emfactory">
+            <primary>OpenJPAEntityManagerFactory</primary>
+          </indexterm>
+          <indexterm>
+            <primary>EntityManagerFactory</primary>
+            <secondary>OpenJPA extensions</secondary>
+            <see>OpenJPAEntityManagerFactory</see>
+          </indexterm>
+          <para>
+      The <classname>org.apache.openjpa.persistence.OpenJPAEntityManagerFactory</classname>
+      interface extends the basic <classname>
+      javax.persistence.EntityManagerFactory</classname> with 
+      OpenJPA-specific features.  The <classname>OpenJPAEntityManagerFactory
+      </classname> offers APIs to obtain 
+      managed and unmanaged <classname>EntityManager</classname>s from 
+      the same factory, to access the OpenJPA data and query caches, and to 
+      perform other OpenJPA-specific operations.  See the
+      <ulink url="../../api/openjpa/persistence/OpenJPAEntityManagerFactory.html">
+      interface Javadoc</ulink> for details.
+      </para>
+        </section>
+        <section id="ref_guide_runtime_em">
+          <title>OpenJPAEntityManager</title>
+          <indexterm zone="ref_guide_runtime_em">
+            <primary>OpenJPAEntityManager</primary>
+          </indexterm>
+          <indexterm>
+            <primary>EntityManager</primary>
+            <secondary>OpenJPA extensions</secondary>
+            <see>OpenJPAEntityManager</see>
+          </indexterm>
+          <para>
+      All OpenJPA <classname>EntityManager</classname>s implement the 
+      <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><classname>org.apache.openjpa.persistence.OpenJPAEntityManager</classname></ulink> 
+      interface.  This interface extends the standard <classname>
+      javax.persistence.EntityManager</classname>.  Just as the
+      standard <classname>EntityManager</classname> is the primary 
+      window into JPA services, the <classname>
+      OpenJPAEntityManager</classname> is the primary window from JPA
+      into OpenJPA-specific functionality.  We strongly 
+      encourage you to investigate the API extensions this interface 
+      contains.
+      </para>
+        </section>
+        <section id="ref_guide_runtime_ejbquery">
+          <title>OpenJPAQuery</title>
+          <indexterm zone="ref_guide_runtime_ejbquery">
+            <primary>OpenJPAQuery</primary>
+          </indexterm>
+          <indexterm>
+            <primary>Query</primary>
+            <secondary>OpenJPA extensions</secondary>
+            <see>OpenJPAQuery</see>
+          </indexterm>
+          <para>
+      OpenJPA extends JPA's standard query functionality with the
+      <classname>org.apache.openjpa.persistence.OpenJPAQuery</classname> interface.  See 
+      its <ulink url="../../api/openjpa/persistence/OpenJPAQuery.html">Javadoc
+      </ulink> for details on the convenience methods it provides.
+      </para>
+        </section>
+        <section id="ref_guide_runtime_ejbextent">
+          <title>Extent</title>
+          <indexterm zone="ref_guide_runtime_ejbextent">
+            <primary>Extent</primary>
+          </indexterm>
+          <indexterm>
+            <primary>Extent</primary>
+            <secondary>OpenJPA extensions</secondary>
+            <see>OpenJPAExtent</see>
+          </indexterm>
+          <para>
+      An <classname>Extent</classname> is a logical view of all persistent
+      instances of a given entity class, possibly including subclasses. 
+      OpenJPA adds the <ulink url="../../api/openjpa/persistence/Extent.html"><classname>org.apache.openjpa.persistence.Extent</classname></ulink> class 
+      to the set of Java Persistence APIs.  The following code illustrates
+      iterating over all instances of the <classname>Magazine</classname>
+      entity, without subclasses:
+      </para>
+          <example id="ref_guide_runtime_ejbextentex">
+            <title>Using a JPA Extent</title>
+            <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+Extent&lt;Magazine&gt; mags = kem.getExtent (Magazine.class, false);
+for (Magazine m : mags)
+    processMagazine (m);
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_runtime_ejbcache">
+          <title>StoreCache</title>
+          <indexterm zone="ref_guide_runtime_ejbcache">
+            <primary>StoreCache</primary>
+          </indexterm>
+          <para>
+      In addition to the <classname>EntityManager</classname> object
+      cache mandated by the JPA specification, OpenJPA includes
+      a flexible datastore-level cache.  You can access this cache
+      from your JPA code using the 
+      <ulink url="../../api/openjpa/persistence/StoreCache.html"><classname>
+      org.apache.openjpa.persistence.StoreCache</classname></ulink> facade.  
+      <xref linkend="ref_guide_cache"/> has detailed information on
+      OpenJPA's data caching system, including the 
+      <classname>StoreCache</classname> facade.
+      </para>
+        </section>
+        <section id="ref_guide_runtime_ejbquerycache">
+          <title>QueryResultCache</title>
+          <indexterm zone="ref_guide_runtime_ejbquerycache">
+            <primary>QueryResultCache</primary>
+          </indexterm>
+          <para>
+      OpenJPA can cache query results as well as persistent object data.  The
+      <ulink url="../../api/openjpa/persistence/QueryResultCache.html"><classname>org.apache.openjpa.persistence.QueryResultCache</classname></ulink> 
+      is an JPA-flavored facade to OpenJPA's internal query cache.  See
+      <xref linkend="ref_guide_cache_query"/> for details on query caching
+      in OpenJPA.
+      </para>
+        </section>
+        <section id="ref_guide_runtime_ejbfetch">
+          <title>FetchPlan</title>
+          <indexterm zone="ref_guide_runtime_ejbfetch">
+            <primary>FetchPlan</primary>
+          </indexterm>
+          <indexterm>
+            <primary>eager fetching</primary>
+            <seealso>FetchPlan</seealso>
+          </indexterm>
+          <para>
+      Many of the aforementioned OpenJPA interfaces give you access to a 
+      <classname>org.apache.openjpa.persistence.FetchPlan</classname>
+      instance.  The <classname>FetchPlan</classname> allows you
+      to exercise some control over how objects are fetched from the 
+      datastore, including <link linkend="ref_guide_dbsetup_lrs">large 
+      result set support</link>, <link linkend="ref_guide_fetch">custom 
+      fetch groups</link>, and <link linkend="ref_guide_locking">lock 
+      levels</link>.  
+      </para>
+          <para>
+      OpenJPA goes one step further, extending <classname>FetchPlan
+      </classname> with
+      <ulink url="../../api/openjpa/persistence/jdbc/JDBCFetchPlan.html"><classname>org.apache.openjpa.persistence.jdbc.JDBCFetchPlan</classname></ulink> to add additional JDBC-specific tuning methods.
+      Unless you have customized OpenJPA to use a non-relational back-end
+      (see <xref linkend="ref_guide_enterprise_abstractstore"/>), all
+      <classname>FetchPlan</classname>s in OpenJPA implement
+      <classname>JDBCFetchPlan</classname>, so feel free to cast
+      to this interface.
+      </para>
+          <para>
+      Fetch plans pass on from parent components to child
+      components.  The <classname>EntityManagerFactory</classname> 
+      settings (via your configuration properties) for things like the 
+      fetch size, result set type, and custom fetch groups are passed on 
+      to the fetch plan of the <classname>
+      EntityManager</classname>s it produces.  The settings 
+      of each <classname>EntityManager</classname>, in turn, are passed 
+      on to each <classname>Query</classname> and <classname>Extent
+      </classname> it returns.  Note that the opposite, however, is not 
+      true.  Modifying the fetch plan of a 
+      <classname>Query</classname> or <classname>Extent</classname> does 
+      not affect the <classname>EntityManager</classname>'s configuration.
+      Likewise, modifying an <classname>EntityManager</classname>'s 
+      configuration does not affect the <classname>
+      EntityManagerFactory</classname>.
+      </para>
+          <para><xref linkend="ref_guide_fetch"/> includes examples using
+      <classname>FetchPlan</classname>s.
+      </para>
+        </section>
+        <section id="ref_guide_runtime_openjpapersistence">
+          <title>OpenJPAPersistence</title>
+          <indexterm zone="ref_guide_runtime_openjpapersistence">
+            <primary>OpenJPAPersistence</primary>
+          </indexterm>
+          <para><ulink url="../../api/openjpa/persistence/OpenJPAPersistence.html"><classname>org.apache.openjpa.persistence.OpenJPAPersistence</classname></ulink> is 
+      a static helper class that adds OpenJPA-specific utility methods to 
+      <classname>javax.persistence.Persistence</classname>.
+      </para>
+        </section>
+      </section>
+      <section id="ref_guide_locking">
+        <title>Object Locking</title>
+        <indexterm zone="ref_guide_locking">
+          <primary>locking</primary>
+        </indexterm>
+        <para>
+  Controlling how and when objects are locked is an important part of 
+  maximizing the performance of your application under load.  This section
+  describes OpenJPA's APIs for explicit locking, as well as its rules for
+  implicit locking.
+  </para>
+        <section id="ref_guide_locking_default">
+          <title>Configuring Default Locking</title>
+          <indexterm zone="ref_guide_locking_default">
+            <primary>locking</primary>
+            <secondary>defaults configuration</secondary>
+          </indexterm>
+          <para><indexterm><primary>locking</primary><secondary>levels</secondary></indexterm><indexterm><primary>ReadLockLevel</primary></indexterm><indexterm><primary>WriteLockLevel</primary></indexterm>
+    You can control OpenJPA's default transactional read and write lock levels
+    through the <link linkend="openjpa.ReadLockLevel"><literal>
+    openjpa.ReadLockLevel</literal></link> and 
+    <link linkend="openjpa.WriteLockLevel"><literal>openjpa.WriteLockLevel
+    </literal></link> configuration properties.  Each property accepts a 
+    value of <literal>none</literal>, <literal>read</literal>, 
+    <literal>write</literal>, or a number corresponding to a lock
+    level defined by the <link linkend="ref_guide_locking_lockmgr">lock 
+    manager</link> in use.  These properties apply only to non-optimistic 
+    transactions; during optimistic transactions, OpenJPA never locks objects 
+    by default.
+    </para>
+          <para><indexterm><primary>LockTimeout</primary></indexterm><indexterm><primary>locking</primary><secondary>timeout</secondary></indexterm>
+    You can control the default amount of time OpenJPA will wait when trying 
+    to obtain locks through the <link linkend="openjpa.LockTimeout"><literal>
+    openjpa.LockTimeout</literal></link> configuration property.  Set this
+    property to the number of milliseconds you are willing to wait for
+    a lock before OpenJPA will throw an exception, or to -1 for no limit.  It
+    defaults to -1.
+    </para>
+          <example id="ref_guide_locking_default_conf">
+            <title>Setting Default Lock Levels</title>
+            <programlisting format="linespecific">
+&lt;property name="openjpa.ReadLockLevel" value="none"/&gt;
+&lt;property name="openjpa.WriteLockLevel" value="write"/&gt;
+&lt;property name="openjpa.LockTimeout" value="30000"/&gt;
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_locking_runtime">
+          <title>Configuring Lock Levels at Runtime</title>
+          <indexterm zone="ref_guide_locking_runtime">
+            <primary>locking</primary>
+            <secondary>runtime configuration</secondary>
+          </indexterm>
+          <para>
+    At runtime, you can override the default lock levels through the
+    <classname>FetchPlan</classname> interface described above.
+    At the beginning of each
+    datastore transaction, OpenJPA initializes the <classname>
+    EntityManager</classname>'s fetch plan with the default lock 
+    levels and timeouts described in the previous section.  By changing the
+    fetch plan's locking properties, you can control how objects 
+    loaded at different points in the transaction are locked.  You can 
+    also use the fetch plan of an individual 
+    <classname>Query</classname> to apply your locking changes only to 
+    objects loaded through that <classname>Query</classname>.
+    </para>
+          <programlisting format="linespecific">
+public LockModeType getReadLockMode ();
+public FetchPlan setReadLockMode (LockModeType mode);
+public LockModeType getWriteLockMode ();
+public FetchPlan setWriteLockMode (LockModeType mode);
+long getLockTimeout ();
+FetchPlan setLockTimeout (long timeout);
+</programlisting>
+          <para>
+    Controlling locking through these runtime APIs works even during
+    optimistic transactions.  At the end of the transaction, OpenJPA resets 
+    the fetch plan's lock levels to <literal>none</literal>.
+    You cannot lock objects outside of a transaction.
+    </para>
+          <example id="ref_guide_locking_fetch">
+            <title>Setting Runtime Lock Levels</title>
+            <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+EntityManager em = ...;
+em.getTransaction ().begin ();
+
+// load stock we know we're going to update at write lock mode
+Query q = em.createQuery ("select s from Stock s where symbol = :s");
+q.setParameter ("s", symbol);
+OpenJPAQuery kq = OpenJPAPersistence.cast (q);
+FetchPlan fetch = kq.getFetchPlan ();
+fetch.setReadLockMode (LockModeType.WRITE);
+fetch.setLockTimeout (3000); // 3 seconds
+Stock stock = (Stock) q.getSingleResult ();
+
+// load an object we don't need locked at none lock mode
+fetch = (OpenJPAPersistence.cast (em)).getFetchPlan ();
+fetch.setReadLockMode (null);
+Market market = em.find (Market.class, marketId);
+
+stock.setPrice (market.calculatePrice (stock));
+em.getTransaction ().commit ();
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_locking_apis">
+          <title>Object Locking APIs</title>
+          <indexterm zone="ref_guide_locking_apis">
+            <primary>locking</primary>
+            <secondary>runtime APIs</secondary>
+          </indexterm>
+          <para>
+    In addition to allowing you to control implicit locking levels, OpenJPA
+    provides explicit APIs to lock objects and to retrieve their current
+    lock level.
+    </para>
+          <programlisting format="linespecific">
+public LockModeType OpenJPAEntityManager.getLockMode (Object pc);
+</programlisting>
+          <para>
+    Returns the level at which the given object is currently locked.
+    </para>
+          <para>
+    In addition to the standard 
+    <ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/EntityManager.html"><methodname>EntityManager.lock (Object, LockModeType)</methodname></ulink> method, the
+    <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><classname>OpenJPAEntityManager</classname></ulink> exposes the following
+    methods to lock objects explicitly:
+    </para>
+          <programlisting format="linespecific">
+public void lock (Object pc);
+public void lock (Object pc, LockModeType mode, long timeout);
+public void lockAll (Object... pcs);
+public void lockAll (Object... pcs, LockModeType mode, long timeout);
+public void lockAll (Collection pcs);
+public void lockAll (Collection pcs, LockModeType mode, long timeout);
+</programlisting>
+          <para>
+    Methods that do not take a lock level or timeout parameter default
+    to the current fetch plan.  The example below demonstrates
+    these methods in action.
+    </para>
+          <example id="ref_guide_locking_explicit">
+            <title>Locking APIs</title>
+            <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+// retrieve the lock level of an object
+OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+Stock stock = ...;
+LockModeType level = kem.getLockMode (stock);
+if (level == OpenJPAModeType.WRITE) ...
+
+...
+
+kem.setOptimistic (true);
+kem.getTransaction ().begin ();
+
+// override default of not locking during an opt trans to lock stock object
+kem.lock (stock, LockModeType.WRITE, 1000);
+stock.setPrice (market.calculatePrice (stock));
+
+kem.getTransaction ().commit ();
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_locking_lockmgr">
+          <title>Lock Manager</title>
+          <indexterm zone="ref_guide_locking_lockmgr">
+            <primary>locking</primary>
+            <secondary>LockManager</secondary>
+          </indexterm>
+          <para><indexterm><primary>LockManager</primary></indexterm>
+    OpenJPA delegates the actual work of locking objects to the system's
+    <ulink url="../apidocs/org/apache/openjpa/kernel/LockManager.html"><classname>
+    org.apache.openjpa.kernel.LockManager</classname></ulink>.  This plugin is controlled
+    by the <link linkend="openjpa.LockManager"><literal>openjpa.LockManager
+    </literal></link> configuration property.  You can write your own lock
+    manager, or use one of the bundled options:
+    </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>pessimistic</literal>: This is an alias for the 
+        <ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.html"><classname>org.apache.openjpa.jdbc.kernel.PessimisticLockManager</classname></ulink>, which uses SELECT FOR UPDATE statements (or the 
+        database's equivalent) to lock the database rows corresponding
+        to locked objects.  This lock manager does not distinguish
+        between read locks and write locks; all locks are write locks. 
+        </para>
+              <para>
+        The <literal>pessimistic</literal> LockManager can be
+        configued to additionally perform the version checking
+        and incrementing behavior of the <literal>version</literal>
+        lock manager described below by setting its
+        <literal>VersionCheckOnReadLock</literal>
+        and <literal>VersionUpdateOnWriteLock</literal> properties:
+        </para>
+              <programlisting format="linespecific">
+&lt;property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=true)"/&gt;
+</programlisting>
+            </listitem>
+            <listitem>
+              <para><literal>none</literal>: An alias for the 
+        <ulink url="../apidocs/org/apache/openjpa/kernel/NoneLockManager.html"><classname>org.apache.openjpa.kernel.NoneLockManager</classname></ulink>, 
+        which does not perform any locking at all.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>sjvm</literal>: An alias for the 
+        <ulink url="../apidocs/org/apache/openjpa/kernel/SingleJVMExclusiveLockManager.html"><classname>org.apache.openjpa.kernel.SingleJVMExclusiveLockManager
+        </classname></ulink>.  This lock manager uses in-memory mutexes
+        to obtain exclusive locks on object ids.  It does not perform
+        any database-level locking.  Also, it does not distinguish
+        between read and write locks; all locks are write locks.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>version</literal>: An alias for the 
+        <ulink url="../apidocs/org/apache/openjpa/kernel/VersionLockManager.html"><classname>org.apache.openjpa.kernel.VersionLockManager
+        </classname></ulink>.  This lock manager does not perform
+        any exclusive locking, but instead ensures read consistency
+        by verifying that the version of all read-locked instances
+        is unchanged at the end of the transaction. Furthermore, a
+        write lock will force an increment to the version at the
+        end of the transaction, even if the object is not
+        otherwise modified. This ensures read consistency with
+        non-blocking behavior.
+        </para>
+              <para>
+        This is the default <literal>openjpa.LockManager</literal>
+        setting in JPA.
+        </para>
+            </listitem>
+          </itemizedlist>
+          <note>
+            <para>
+      In order for the <literal>version</literal> lock manager
+      to prevent the dirty read phenomenon, the underlying data
+      store's transaction isolation level must be set to
+      the equivalent of "read committed" or higher.
+      </para>
+          </note>
+          <example id="ref_guide_locking_disable">
+            <title>Disabling Locking</title>
+            <programlisting format="linespecific">
+&lt;property name="openjpa.LockManager" value="none"/&gt;
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_locking_rules">
+          <title>Rules for Locking Behavior</title>
+          <indexterm zone="ref_guide_locking_rules">
+            <primary>locking</primary>
+            <secondary>behavior</secondary>
+          </indexterm>
+          <indexterm zone="ref_guide_locking_rules">
+            <primary>lazy loading</primary>
+            <secondary>locking behavior</secondary>
+          </indexterm>
+          <para>
+    Advanced persistence concepts like lazy-loading and object uniquing 
+    create several locking corner-cases.  The rules below outline OpenJPA's 
+    implicit locking behavior in these cases. 
+    </para>
+          <orderedlist>
+            <listitem>
+              <para>
+        When an object's state is first read within a transaction, the 
+        object is locked at the fetch plan's current read lock
+        level.  Future reads of additional lazy state for the object 
+        will use the same read lock level, even if the fetch 
+        plan's level has changed.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        When an object's state is first modified within a transaction, 
+        the object is locked at the write lock level in effect when
+        the object was first read, even if the fetch plan's 
+        level has changed.  If the object was not read previously, the 
+        current write lock level is used.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        When objects are accessed through a persistent relation field,
+        the related objects are loaded with the fetch plan's 
+        current lock levels, not the lock levels of the object owning 
+        the field.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        Whenever an object is accessed within a transaction,
+        the object is re-locked at the current read lock
+        level.  The current read and write lock levels become those that
+        the object "remembers" according to rules one and two above.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        If you lock  an object explicitly through the APIs demonstrated
+        above, it is re-locked at the specified level.  This level 
+        also becomes both the read and write level that the object 
+        "remembers" according to rules one and two above.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        When an object is already locked at a given lock level, 
+        re-locking at a lower level has no effect.  Locks cannot be
+        downgraded during a transaction.
+        </para>
+            </listitem>
+          </orderedlist>
+        </section>
+        <section id="ref_guide_locking_issues">
+          <title>Known Issues and Limitations</title>
+          <indexterm zone="ref_guide_locking_issues">
+            <primary>locking</primary>
+            <secondary>caveats</secondary>
+          </indexterm>
+          <para>
+    Due to performance concerns and database limitations, locking cannot
+    be perfect.  You should be aware of the issues outlined in this 
+    section, as they may affect your application.
+    </para>
+          <itemizedlist>
+            <listitem>
+              <para>
+        Typically, during optimistic transactions OpenJPA does not 
+        start an actual database transaction until you flush or the 
+        optimistic transaction commits.  This allows for very long-lived
+        transactions without consuming database resources.
+        When using the default lock manager, however, OpenJPA must begin a 
+        database transaction whenever you decide to lock an object 
+        during an optimistic transaction.  This is because the
+        default lock manager uses database locks, and databases cannot
+        lock rows without a transaction in progress.  OpenJPA will log
+        an INFO message to the <literal>openjpa.Runtime</literal> logging
+        channel when it begins a datastore transaction just to lock
+        an object.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        In order to maintain reasonable performance levels when 
+        loading object state, OpenJPA can only guarantee that an 
+        object is locked at the proper lock level <emphasis>after
+        </emphasis> the state has been retrieved from the database.
+        This means that it is technically possible for another 
+        transaction to "sneak in" and modify the database record after
+        OpenJPA retrieves the state, but before it locks the object.  The
+        only way to positively guarantee that the object is locked and
+        has the most recent state to refresh the object after locking 
+        it.
+        </para>
+              <para>
+        When using the default lock manager, the case above can only
+        occur when OpenJPA cannot issue the state-loading SELECT as a
+        locking statement due to database limitations.  For example, 
+        some databases cannot lock SELECTs that use joins.
+        The default lock manager will log an INFO message to the
+        <literal>openjpa.Runtime</literal> logging channel whenever it 
+        cannot lock the initial SELECT due to database limitations.
+        By paying attention to these log messages, you can see where 
+        you might consider using an object refresh to guarantee that 
+        you have the most recent state, or where you might rethink the 
+        way you load the state in question to circumvent the database
+        limitations that prevent OpenJPA from issuing a locking SELECT in 
+        the first place.
+        </para>
+            </listitem>
+          </itemizedlist>
+        </section>
+      </section>
+      <section id="ref_guide_savepoints">
+        <title>Savepoints</title>
+        <indexterm zone="ref_guide_savepoints">
+          <primary>savepoint</primary>
+        </indexterm>
+        <para>
+  Savepoints allow for fine grained control over the transactional behavior
+  of your application.  OpenJPA's savepoint API allow you to set intermediate
+  rollback points in your transaction.  You can then choose to rollback 
+  changes made only after a specific savepoint, then commit or continue 
+  making new changes in the transaction.  This feature is useful for 
+  multi-stage transactions, such as editing a set of objects over several 
+  web pages or user screens.  Savepoints also provide more flexibilty 
+  to conditional transaction behavior, such as choosing to commit or 
+  rollback a portion of the transaction based on the results of the 
+  changes.  This chapter describes how to use and configure OpenJPA savepoints.
+  </para>
+        <section id="reg_guide_savepoints_using">
+          <title>Using Savepoints</title>
+          <para>
+    OpenJPA's
+    <phrase><ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><classname>OpenJPAEntityManager</classname></ulink></phrase>
+    
+    
+    have the following methods to control savepoint behavior.
+    Note that the savepoints work in tandem with the current
+    transaction.  This means that savepoints require an open transaction, 
+    and that a rollback of the transaction will rollback all of 
+    the changes in the transaction regardless of any savepoints set.
+    </para>
+          <programlisting format="linespecific">
+void setSavepoint (String name);
+void releaseSavepoint (String name);
+void rollbackToSavepoint (String name);
+</programlisting>
+          <para>
+    To set a savepoint, simply call <methodname>setSavepoint</methodname>, 
+    passing in a symbolic savepoint name.  
+    This savepoint will define a point at which you can preserve
+    the state of transactional objects for the duration of the current
+    transaction.
+    </para>
+          <para>
+    Having set a named savepoint, you can rollback changes made after that
+    point by calling <methodname>rollbackToSavepoint</methodname>.  This 
+    method will keep the current transaction active,
+    while restoring all transactional instances back to their saved state.
+    Instances that were deleted after the save point will no longer
+    be marked for deletion.  Similarly, transient instances that were
+    made persistent after the savepoint will become transient again.  
+    Savepoints made after this savepoint will be released and no longer 
+    valid, although you can still set new savepoints.  Savepoints will also
+    be cleared after the current transaction is committed or rolled back.
+    </para>
+          <para>
+    If a savepoint is no longer needed, you can release any resources
+    such as in memory state and datastore resources by calling
+    <methodname>releaseSavepoint</methodname>.
+    This method should not be called for savepoints that have been 
+    released automatically through other means, such as commit of a 
+    transaction or rollback to a prior savepoint.  While savepoints
+    made after this savepoint will also be released, there are no other
+    effects on the current transaction.
+    </para>
+          <para>
+    The following simple example illustrates setting, releasing, and
+    rolling back to a savepoint.
+    </para>
+          <example id="ref_guide_savepoints_example">
+            <title>Using Savepoints</title>
+            <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+kem.getTransaction ().begin ();
+
+Magazine mag = kem.find (Magazine.class, id);
+mag.setPageCount (300);
+kem.setSavepoint ("pages");
+
+mag.setPrice (mag.getPageCount () * pricePerPage);
+// we decide to release pages since price depends on pages.
+kem.releaseSavepoint ("pages");
+kem.setSavepoint ("price");
+
+mag.setPrice (testPrice);
+...
+
+// we determine the test price is not good
+kem.rollbackToSavepoint ("price");
+
+// the price is now restored to mag.getPageCount () * pricePerPage
+kem.getTransaction ().commit ();
+</programlisting>
+          </example>
+        </section>
+        <section id="ref_guide_savepoints_conf">
+          <title>Configuring Savepoints</title>
+          <para>
+    OpenJPA uses the <ulink url="javadoc/openjpa/kernel/SavepointManager"><classname>org.apache.openjpa.kernel.SavepointManager</classname></ulink> 
+    <link linkend="ref_guide_conf_plugins">plugin</link> to handle
+    perserving the savepoint state.  OpenJPA includes the following
+    <classname>SavepointManager</classname> plugins:
+    </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>in-mem</literal>: The default.  This is an alias
+        for the <ulink url="org.apache.openjpa.kernel.InMemorySavepointManager"><classname>org.apache.openjpa.kernel.InMemorySavepointManager</classname></ulink>.  This plugin stores all state, including field 
+        values, in memory.  Due to this behavior, each set savepoint 
+        is designed for small to medium transactional object counts.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>jdbc</literal>: This is an alias for the <ulink url="org.apache.openjpa.jdbc.kernel.JDBCSavepointManager"><classname>
+        org.apache.openjpa.jdbc.kernel.JDBCSavepointManager</classname></ulink>.
+        This plugin requires <literal>JDBC 3</literal> and <classname>
+        java.sql.Savepoint</classname> support to operate.  Note that 
+        this plugin implements savepoints by issuing a flush to the 
+        database.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>oracle</literal>: This is an alias for the <ulink url="org.apache.openjpa.jdbc.sql.OracleSavepointManager"><classname>
+        org.apache.openjpa.jdbc.sql.OracleSavepointManager</classname></ulink>.
+        This plugin operates similarly to the <literal>JDBC</literal>
+        plugin; however, it uses Oracle-specific calls.
+        This plugin requires using the Oracle JDBC driver and database,
+        versions <literal>9.2</literal> or higher.  Note that this 
+        plugin implements savepoints by issuing a flush to the database.
+        </para>
+            </listitem>
+          </itemizedlist>
+        </section>
+      </section>
+      <section id="ref_guide_enterprise_queryext">
+        <title>Query Language Extensions</title>
+        <indexterm zone="ref_guide_enterprise_queryext">
+          <primary>Query</primary>
+          <secondary>language extensions</secondary>
+          <seealso>JPQL</seealso>
+        </indexterm>
+        <para>
+  JPQL is a powerful, easy-to-use query language, but you may
+  occasionally find it limiting in some way. To circumvent the
+  limitations of JPQL, OpenJPA provides extensions to the JPQL language, and
+  allows you to extend it as well.
+  </para>
+<!-- ### EJBDOC : remove note when parser upgraded -->
+        <warning>
+          <para>
+    The JPQL parser in this release does not yet allow extensions.  They
+    will be made available to JPQL users in a future release.
+    </para>
+        </warning>
+        <section id="ref_guide_enterprise_queryext_jdoql">
+          <title>Filter Extensions</title>
+          <indexterm zone="ref_guide_enterprise_queryext_jdoql">
+            <primary>JPQL</primary>
+            <secondary>language extension</secondary>
+          </indexterm>
+          <para>
+    Filter extensions are custom methods that you can use in your
+    query filter, having, ordering, and result strings.  OpenJPA provides 
+    some built-in filter extensions, and you can develop your own custom 
+    extensions as needed. You can optionally preface all filter extensions 
+    with <literal>ext:</literal> in your query string.  For example, the 
+    following example uses a hypothetical <literal>firstThreeChars
+    </literal> extension to search for cities whose name begins with
+    the 3 characters 'H', 'a', 'r'.
+    </para>
+          <example id="ref_guide_enterprise_queryext_jdoql_ext">
+            <title>Basic Filter Extension</title>
+            <programlisting format="linespecific">
+Query q = em.createQuery ("select c from City c where c.name.ext:firstThreeChars () = 'Har'");
+List results = q.getResultList ();
+</programlisting>
+          </example>
+          <para>
+    Note that it is perfectly OK to chain together extensions.  For
+    example, let's modify our search above to be case-insensitive using
+    another hypothetical extension, <literal>equalsIgnoreCase</literal>:
+    </para>
+          <example id="ref_guide_enterprise_queryext_jdoql_chain">
+            <title>Chaining Filter Extensions</title>
+            <programlisting format="linespecific">
+Query query = em.createQuery ("select c from City c where "
+    + "c.name.ext:firstThreeChars ().ext:equalsIgnoreCase ('Har')");
+List results = q.getResultList ();
+</programlisting>
+          </example>
+          <para>
+    Finally, when using filter extensions you must be aware that any
+    SQL-specific extensions can only execute against the database, and 
+    cannot be used for in-memory queries (recall that OpenJPA executes queries
+    in-memory when you supply a candidate collection rather than a 
+    class, or when you set the <literal>IgnoreChanges</literal>
+    and <literal>FlushBeforeQueries</literal> properties to 
+    <literal>false</literal> and you execute a query within a transaction 
+    in which you've modified data that may affect the results).
+    </para>
+          <section id="ref_guide_enterprise_queryext_jdoql_included">
+            <title>Included Filter Extensions</title>
+            <para>
+      OpenJPA includes two default filter extensions to enhance the power
+      of your queries.
+      </para>
+            <itemizedlist>
+              <listitem>
+                <para><indexterm><primary>JPQL</primary><secondary>language extension</secondary><tertiary>getColumn</tertiary></indexterm><literal>getColumn</literal>: Places the proper alias for
+          the given column name into the SELECT statement that is 
+          issued.  This extension cannot be used for in-memory 
+          queries.  When traversing relations, the column is assumed 
+          to be in the primary table of the related type.
+          </para>
+                <programlisting format="linespecific">
+select e from Employee e where e.company.address.ext:getColumn ('ID') = 5
+</programlisting>
+              </listitem>
+              <listitem>
+                <para><indexterm><primary>JPQL</primary><secondary>language extension</secondary><tertiary>sql</tertiary></indexterm><literal>sql</literal>: Embeds the given SQL argument
+          into the SELECT statement.
+          This extension cannot be used for in-memory queries.
+          </para>
+                <programlisting format="linespecific">
+select p from Product p where p.price &lt; ext:sql ('(SELECT AVG(PRICE) FROM PRODUCTS)')
+</programlisting>
+              </listitem>
+            </itemizedlist>
+          </section>
+          <section id="ref_guide_enterprise_queryext_jdoql_custom">
+            <title>Developing Custom Filter Extensions</title>
+            <indexterm zone="ref_guide_enterprise_queryext_jdoql_custom">
+              <primary>JPQL</primary>
+              <secondary>language extension</secondary>
+              <tertiary>custom</tertiary>
+            </indexterm>
+            <para>
+      You can write your own extensions by implementing the
+      <ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/exps/JDBCFilterListener.html"><classname>org.apache.openjpa.jdbc.kernel.exps.JDBCFilterListener</classname></ulink> interface.  View the Javadoc documentation for details.  
+      Additionally, the source for all of OpenJPA's built-in query 
+      extensions is included in your OpenJPA download to get you started.  
+      The built-in extensions reside in the <filename>
+      src/openjpa/kernel/exps</filename> and <filename>
+      src/openjpa/jdbc/kernel/exps</filename> directories of your 
+      distribution.
+      </para>
+          </section>
+          <section id="ref_guide_enterprise_queryext_jdoql_conf">
+            <title>Configuring Filter Extensions</title>
+            <indexterm zone="ref_guide_enterprise_queryext_jdoql_conf">
+              <primary>JPQL</primary>
+              <secondary>language extension</secondary>
+              <tertiary>configuration</tertiary>
+            </indexterm>
+            <para>
+      There are two ways to register your custom filter extensions with 
+      OpenJPA:
+      </para>
+            <itemizedlist>
+              <listitem>
+                <para><emphasis>Registration by properties:</emphasis>
+          You can register custom filter extensions by setting the
+          <link linkend="openjpa.FilterListeners"><literal>
+          openjpa.FilterListeners</literal></link> configuration 
+          property to a comma-separated list of plugin strings
+          (see <xref linkend="ref_guide_conf_plugins"/>)
+          describing your extensions classes.  Extensions 
+          registered in this fashion must have a public no-arg 
+          constructor.  They must also be thread safe, because they 
+          will be shared across all queries.
+          </para>
+              </listitem>
+              <listitem>
+                <para><emphasis>Per-query registration:</emphasis>  You can 
+          register filter extensions for an 
+          individual <classname>Query</classname> through the
+          <methodname>OpenJPAQuery.addFilterListener</methodname>
+          method.  You might use per-query registration for very 
+          specific extensions that do not apply globally.
+          </para>
+                <para>
+          See the <classname>OpenJPAQuery</classname>
+          <ulink url="../../api/openjpa/persistence/OpenJPAQuery.html">Javadoc
+          </ulink> for details.
+          </para>
+              </listitem>
+            </itemizedlist>
+          </section>
+        </section>
+        <section id="ref_guide_aggregates_custom">
+          <title>Aggregate Extensions</title>
+          <indexterm zone="ref_guide_aggregates_custom">
+            <primary>JPQL</primary>
+            <secondary>aggregate extension</secondary>
+          </indexterm>
+          <para>
+    Just as you can write your own filter methods, you can write your 
+    own query aggregates by implementing the
+    <ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/exps/JDBCAggregateListener.html"><classname>org.apache.openjpa.jdbc.kernel.exps.JDBCAggregateListener</classname></ulink> interface.  View the Javadoc documentation for details.  When
+    using your custom aggregates in result or having query clauses, you can
+    optionally prefix the function name with <literal>ext:</literal> to 
+    identify it as an extension.
+    </para>
+          <section id="ref_guide_aggregates_conf">
+            <title>Configuring Query Aggregates</title>
+            <indexterm zone="ref_guide_aggregates_conf">
+              <primary>JPQL</primary>
+              <secondary>aggregate extension</secondary>
+              <tertiary>configuration</tertiary>
+            </indexterm>
+            <para>
+      There are two ways to register your custom query aggregates with 
+      OpenJPA:
+      </para>
+            <itemizedlist>
+              <listitem>
+                <para><emphasis>Registration by properties:</emphasis>
+          You can register custom query aggregates by setting the
+          <link linkend="openjpa.AggregateListeners"><literal>
+          openjpa.AggregateListeners</literal></link> configuration 
+          property to a comma-separated list of plugin strings 
+          (see <xref linkend="ref_guide_conf_plugins"/>)
+          describing your aggregate implementation.  Aggregates 
+          registered in this fashion must have a public
+          no-arg constructor.  They must also be thread safe,
+          because they will be shared across all queries.
+          </para>
+              </listitem>
+              <listitem>
+                <para><emphasis>Per-query registration:</emphasis> 
+          You can register query aggregates for an individual 
+          <classname>Query</classname> through the 
+          <methodname>OpenJPAQuery.addAggregateListener</methodname>
+          method.  You might use per-query registration for
+          very specific aggregates that do not apply globally.
+          </para>
+                <para>
+          See the <classname>OpenJPAQuery</classname>
+          <ulink url="../../api/openjpa/persistence/OpenJPAQuery.html">Javadoc
+          </ulink> for details.
+          </para>
+              </listitem>
+            </itemizedlist>
+          </section>
+        </section>
+        <section id="ref_guide_enterprise_methodql">
+          <title>MethodQL</title>
+          <indexterm zone="ref_guide_enterprise_methodql">
+            <primary>MethodQL</primary>
+          </indexterm>
+          <indexterm>
+            <primary>Query</primary>
+            <secondary>MethodQL</secondary>
+            <see>MethodQL</see>
+          </indexterm>
+          <para>
+    If JPQL and SQL queries do not match your needs, OpenJPA also allows you 
+    to name a Java method to use to load a set of objects.
+    In a <emphasis>MethodQL</emphasis> query, the query string 
+    names a static method to invoke to determine the matching objects:
+    </para>
+          <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+// the method query language is 'openjpa.MethodQL'.
+// set the query string to the method to execute, including full class name; if
+// the class is in the candidate class' package or in the query imports, you
+// can omit the package; if the method is in the candidate class, you can omit
+// the class name and just specify the method name
+OpenJPAEntityManager kem = OpenJPAPersistence.cast (emf);
+OpenJPAQuery q = kem.createQuery ("openjpa.MethodQL", "com.xyz.Finder.getByName");
+
+// set the type of objects that the method returns
+q.setResultClass (Person.class);
+
+// parameters are passed the same way as in standard queries
+q.setParameter ("firstName", "Fred").setParameter ("lastName", "Lucas");
+
+// this executes your method to get the results
+List results = q.getResultList ();
+</programlisting>
+          <para>
+    For datastore queries, the method must have the following signature:
+    </para>
+          <programlisting format="linespecific">
+public static <ulink url="../apidocs/org/apache/openjpa/lib/rop/ResultObjectProvider.html">ResultObjectProvider</ulink> xxx(<ulink url="../apidocs/org/apache/openjpa/kernel/StoreContext.html">StoreContext</ulink> ctx, 
+    <ulink url="../apidocs/org/apache/openjpa/meta/ClassMetaData.html">ClassMetaData</ulink> meta, boolean subclasses, Map params, <ulink url="../apidocs/org/apache/openjpa/kernel/FetchConfiguration.html">FetchConfiguration</ulink> fetch)
+</programlisting>
+          <para>
+    The returned result object provider should produce objects of the 
+    candidate class that match the method's search criteria.  If the
+    returned objects do not have all fields in the given fetch configuration
+    loaded, OpenJPA will make additional trips to the datastore as necessary
+    to fill in the data for the missing fields.
+    </para>
+          <para>
+    In-memory execution is slightly different, taking in one object
+    at a time and returning a boolean on whether the object matches the
+    query:
+    </para>
+          <programlisting format="linespecific">
+public static boolean xxx(<ulink url="../apidocs/org/apache/openjpa/kernel/StoreContext.html">StoreContext</ulink> ctx, <ulink url="../apidocs/org/apache/openjpa/meta/ClassMetaData.html">ClassMetaData</ulink> meta, 
+    boolean subclasses, Object obj, Map params, <ulink url="../apidocs/org/apache/openjpa/kernel/FetchConfiguration.html">FetchConfiguration</ulink> fetch)
+</programlisting>
+          <para>
+    In both method versions, the given <literal>params</literal> map 
+    contains the names and values of all the parameters for the query.
+    </para>
+        </section>
+      </section>
+      <section id="ref_guide_sequence">
+        <title>Generators</title>
+        <indexterm zone="ref_guide_sequence">
+          <primary>generators</primary>
+          <secondary>Seq interface</secondary>
+        </indexterm>
+        <para>
+    The JPA Overview's <xref linkend="jpa_overview_mapping"/> details
+    using generators to automatically populate identity fields in JPA.
+    </para>
+        <para>
+    OpenJPA represents all generators internally with the 
+    <ulink url="../apidocs/org/apache/openjpa/kernel/Seq.html"><classname>org.apache.openjpa.kernel.Seq</classname></ulink> interface.  This 
+    interface supplies all the context you need to create your own custom
+    generators, including the current persistence environment,
+    the JDBC <classname>DataSource</classname>, and other essentials.  
+    The <ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/AbstractJDBCSeq.html"><classname>org.apache.openjpa.jdbc.kernel.AbstractJDBCSeq</classname></ulink> helps
+    you create custom JDBC-based sequences.
+    OpenJPA also supplies the following built-in <classname>Seq</classname>s:
+    </para>
+        <itemizedlist>
+          <listitem>
+            <para><indexterm><primary>generators</primary><secondary>table</secondary></indexterm><literal>table</literal>: This is OpenJPA's default implementation.
+        It is an alias for the
+        <ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.html"><classname>org.apache.openjpa.jdbc.kernel.TableJDBCSeq</classname></ulink>
+        class.  The <classname>TableJDBCSeq</classname> uses a special
+        single-row table to store a global sequence number.  If the 
+        table does not already exist, it is created the first time you 
+        run the <link linkend="ref_guide_mapping_mappingtool">
+        mapping tool</link>'s on a class that requires it.  You can also
+        use the class' <methodname>main</methodname> method or the
+        <literal>sequencetable</literal> shell/bat script to manipulate
+        the table; see the <methodname>TableJDBCSeq.main</methodname> 
+        method Javadoc for usage details.
+        </para>
+            <para>
+        This <classname>Seq</classname> has the following properties:
+        </para>
+            <itemizedlist>
+              <listitem>
+                <para><literal>Table</literal>: The name of the sequence 
+            number table to use.  Defaults to 
+            <literal>OPENJPA_SEQUENCE_TABLE</literal>.
+            </para>
+              </listitem>
+              <listitem>
+                <para><literal>PrimaryKeyColumn</literal>: The name of
+            the primary key column for the sequence table.
+            Defaults to <literal>ID</literal>.
+            </para>
+              </listitem>
+              <listitem>
+                <para><literal>SequenceColumn</literal>:  The name of 
+            the column that will hold the current sequence
+            value.  Defaults to <literal>SEQUENCE_VALUE</literal>.
+            </para>
+              </listitem>
+              <listitem>
+                <para><literal>Allocate</literal>: The number of values to
+            allocate on each database trip.  Defaults to 
+            50, meaning the class will set aside the next 50 
+            numbers each time it accesses the sequence table, which
+            in turn means it only has to make a database trip to 
+            get new sequence numbers once every 50 sequence number
+            requests.
+            </para>
+              </listitem>
+            </itemizedlist>
+          </listitem>
+          <listitem>
+            <para><indexterm><primary>generators</primary><secondary>class-table</secondary></indexterm><literal>class-table</literal>: This is an alias for the
+        <ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/ClassTableJDBCSeq.html"><classname>org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq
+        </classname></ulink>.  This <classname>Seq</classname> is like
+        the <classname>TableJDBCSeq</classname> above, but maintains a 
+        separate table row, and therefore a separate sequence number,
+        for each base persistent class. It has all the properties of 
+        the <classname>TableJDBCSeq</classname>.  Its table name 
+        defaults to <literal>OPENJPA_SEQUENCES_TABLE</literal>.  It
+        also adds the following properties:
+        </para>
+            <itemizedlist>
+              <listitem>
+                <para><literal>IgnoreUnmapped</literal>: Whether to ignore
+            unmapped base classes, and instead use one row per
+            least-derived mapped class.  Defaults to
+            <literal>false</literal>.
+            </para>
+              </listitem>
+              <listitem>
+                <para><literal>UseAliases</literal>: Whether to use
+            each class' entity name as the primary key value of each
+            row, rather than the full class name.  Defaults to
+            <literal>false</literal>.
+            </para>
+              </listitem>
+            </itemizedlist>
+            <para>
+        As with the <classname>TableJDBCSeq</classname>, the <classname>
+        ClassTableJDBCSeq</classname> creates its table automatically
+        during mapping tool runs.  However, you can manually manipulate
+        the table through the class' <methodname>main</methodname> 
+        method, or through the <literal>classsequencetable</literal>
+        shell/bat script.  See the Javadoc for the <methodname>
+        ClassTableJDBCSeq.main</methodname> method for usage details.
+        </para>
+          </listitem>
+          <listitem>
+            <para><indexterm><primary>generators</primary><secondary>value-table</secondary></indexterm><literal>value-table</literal>: This is an alias for the
+        <ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/ValueTableJDBCSeq.html"><classname>org.apache.openjpa.jdbc.kernel.ValueTableJDBCSeq
+        </classname></ulink>.  This <classname>Seq</classname> is like
+        the <classname>ClassTableJDBCSeq</classname> above, but has
+        an arbitrary number of rows for sequence values, rather than
+        a fixed pattern of one row per class.   Its table
+        defaults to <literal>OPENJPA_SEQUENCES_TABLE</literal>.
+        It has all the properties of the 
+        <classname>TableJDBCSeq</classname>, plus:
+        </para>
+            <itemizedlist>
+              <listitem>
+                <para><literal>PrimaryKeyValue</literal>: The primary key
+            value used by this instance.  
+            </para>
+              </listitem>
+            </itemizedlist>
+            <para>
+        As with the <classname>TableJDBCSeq</classname>, the <classname>
+        ValueTableJDBCSeq</classname> creates its table automatically 
+        during mapping tool runs.  However, you can manually manipulate
+        the table through the class' <methodname>main</methodname> 
+        method, or through the <literal>valuesequencetable</literal>
+        shell/bat script.  See the Javadoc for the <methodname>
+        ValueTableJDBCSeq.main</methodname> method for usage details.
+        </para>
+          </listitem>
+          <listitem>
+            <para><indexterm><primary>generators</primary><secondary>native</secondary></indexterm><literal>native</literal>: This is an alias for the
+        <ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.html"><classname>org.apache.openjpa.jdbc.kernel.NativeJDBCSeq</classname></ulink>.
+        Many databases have a concept of "native sequences" - a 
+        built-in mechanism for obtaining incrementing 
+        numbers.  For example, in Oracle, you can create a database 
+        sequence with a statement like <literal>CREATE SEQUENCE 
+        MYSEQUENCE</literal>.  Sequence values can then be 
+        atomically obtained and incremented with the statement 
+        <literal>SELECT MYSEQUENCE.NEXTVAL FROM DUAL</literal>.
+        OpenJPA provides support for this common mechanism of 
+        sequence generation with the <classname>
+        NativeJDBCSeq</classname>, which accepts the following 
+        properties:
+        </para>
+            <itemizedlist>
+              <listitem>
+                <para><literal>Sequence</literal>: The name of the database 
+            sequence.  Defaults to <literal>OPENJPA_SEQUENCE</literal>.
+            </para>
+              </listitem>
+              <listitem>
+                <para><literal>InitialValue</literal>: The initial sequence
+            value.  Defaults to 1.
+            </para>
+              </listitem>
+              <listitem>
+                <para><literal>Increment</literal>: The amount the sequence
+            increments.  Defaults to 1.
+            </para>
+              </listitem>
+              <listitem>
+                <para><literal>Allocate</literal>: Some database can allocate
+            values in-memory to service subsequent sequence requests
+            faster. 
+            </para>
+              </listitem>
+            </itemizedlist>
+          </listitem>
+          <listitem>
+            <para><indexterm><primary>generators</primary><secondary>time</secondary></indexterm><literal>time</literal>: This is an alias for the
+        <ulink url="../apidocs/org/apache/openjpa/kernel/TimeSeededSeq.html"><classname>org.apache.openjpa.kernel.TimeSeededSeq</classname></ulink>.
+        This type uses an in-memory static counter, initialized to the 
+        current time in milliseconds and monotonically incremented for 
+        each value requested.  It is only suitable for single-JVM 
+        environments.
+        </para>
+          </listitem>
+        </itemizedlist>
+        <para>
+    You can use JPA <literal>SequenceGenerator</literal>s to describe any
+    built-in <classname>Seq</classname>s or your own <classname>Seq
+    </classname> implementation.  Set the <literal>sequenceName</literal> 
+    attribute to a plugin string describing your choice.  See 
+    <xref linkend="jpa_overview_mapping_sequence"/> in the JPA
+    Overview for details on defining <literal>SequenceGenerator</literal>s.
+    </para>
+        <para>
+    See <xref linkend="ref_guide_conf_plugins"/> for plugin string 
+    formatting.
+    </para>
+        <example id="ref_guide_sequence_named">
+          <title>Named Seq Sequence</title>
+          <programlisting format="linespecific">
+@Entity
+@Table(name="AUTO")
+public class Author
+{
+    @Id
+    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="AuthorSeq")
+    @SequenceGenerator(name="AuthorSeq" sequence="table(Table=AUTO_SEQ, Increment=100)")
+    @Column(name="AID")
+    private long id;
+ 
+    ...
+}
+</programlisting>
+          <para>
+      Note that if you want to use a plugin string without any arguments,
+      you must still suffix the plugin type with <literal>()</literal>
+      to differentiate it from a sequence name in the <literal>
+      SequenceGenerator.sequence</literal> attribute:
+      </para>
+          <programlisting format="linespecific">
+@SequenceGenerator(name="AuthorSeq", sequence="table()")
+</programlisting>
+        </example>
+        <para>
+    OpenJPA maintains a <emphasis>system</emphasis> sequence to generate 
+    datastore identity values for classes that do not declare a specific 
+    datastore identity strategy.  You can configure the system sequence 
+    through the <link linkend="openjpa.Sequence"><literal>openjpa.Sequence
+    </literal></link> configuration property.  This property accepts a 
+    plugin string describing a <classname>Seq</classname> instance.
+    </para>
+        <example id="ref_guide_sequence_systemex">
+          <title>System Sequence Configuration</title>
+          <programlisting format="linespecific">
+&lt;property name="openjpa.Sequence" value="table(Table=OPENJPASEQ, Increment=100)"/&gt;
+</programlisting>
+        </example>
+        <para>
+    In JPA, set your <literal>GeneratedValue</literal> 
+    annotation's <literal>strategy</literal> attribute to 
+    <literal>AUTO</literal> to use the configured system sequence.  Or,
+    because <literal>AUTO</literal> is the default strategy, use the
+    annotation without attributes:
+    </para>
+        <programlisting format="linespecific">
+@GeneratedValue
+private long id;
+</programlisting>
+        <section id="ref_guide_sequence_runtime">
+          <title>Runtime Access</title>
+          <indexterm zone="ref_guide_sequence_runtime">
+            <primary>Sequence</primary>
+            <secondary>runtime access</secondary>
+          </indexterm>
+          <para>
+      OpenJPA allows you to access named generators at runtime
+      through the <methodname>OpenJPAEntityManager.getNamedGenerator
+      </methodname> method:
+      </para>
+          <programlisting format="linespecific">
+public Generator getNamedGenerator (String name);
+</programlisting>
+          <para>
+      The returned <ulink url="../../api/openjpa/persistence/Generator.html"><classname>org.apache.openjpa.persistence.Generator</classname></ulink> is a 
+      facade over an internal OpenJPA <classname>Seq</classname>.
+      </para>
+          <para>
+      The <classname>OpenJPAEntityManager</classname> includes 
+      additional APIs to retrieve the identity generator of any class, 
+      or the generator of any field.  With these APIs, you do not have
+      to know the generator name.  Additionally, they allow you to access
+      the implicit generator used by default for datastore identity
+      classes.  See the 
+      <ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
+      Javadoc</ulink> for the <methodname>
+      OpenJPAEntityManager.getIdentityGenerator</methodname> and 
+      <methodname>OpenJPAEntityManager.getFieldGenerator</methodname> 
+      methods for API details.  
+      </para>
+        </section>
+      </section>
+      <section id="ref_guide_runtime_pm_event">
+        <title>Transaction Events</title>
+        <indexterm zone="ref_guide_runtime_pm_event">
+          <primary>transactions</primary>
+          <secondary>events</secondary>
+        </indexterm>
+        <para>
+    The OpenJPA runtime supports
+    broadcasting transaction-related events.  By registering one or more
+    <ulink url="../apidocs/org/apache/openjpa/event/TransactionListener.html"><classname>org.apache.openjpa.event.TransactionListener</classname></ulink>s, you can 
+    receive notifications when transactions begin, flush, rollback, commit,
+    and more.  Where appropriate, event notifications include the set of 
+    persistence-capable objects participating in the transaction.
+    </para>
+        <programlisting format="linespecific">
+public void addTransactionListener (Object listener);
+public void removeTransactionListener (Object listener);
+</programlisting>
+        <para>
+    These <classname>OpenJPAEntityManager</classname> methods allow you
+    to add and remove listeners.
+    </para>
+        <para>
+    For details on the transaction framework, see the <literal>
+    org.apache.openjpa.event</literal> package
+    <ulink url="../apidocs/org/apache/openjpa/event/package.html">Javadoc</ulink>.
+    Also see <xref linkend="ref_guide_event"/> for a description of
+    OpenJPA's remote event support.
+    </para>
+      </section>
+      <section id="ref_guide_enterprise_abstractstore">
+        <title>Non-Relational Stores</title>
+        <para>
+    It is possible to adapt OpenJPA to access a non-relational datastore
+    by creating an implementation of the 
+    <ulink url="../apidocs/org/apache/openjpa/kernel/StoreManager.html"><literal>org.apache.openjpa.kernel.StoreManager</literal></ulink> interface. OpenJPA
+    provides an abstract <literal>StoreManager</literal> implementation to 
+    facilitate this process. See the <literal>org.apache.openjpa.abstractstore</literal> 
+    package <ulink url="../apidocs/org/apache/openjpa/abstractstore">Javadoc</ulink> for 
+    details.  
+    
+    </para>
+      </section>
+    </chapter>

Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/samples_guide.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/samples_guide.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/samples_guide.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/samples_guide.xml Tue Aug 22 14:28:53 2006
@@ -0,0 +1,137 @@
+
+    <chapter id="samples_guide">
+      <title>OpenJPA Sample Code</title>
+      <para>
+  The OpenJPA distribution comes with a number of examples that
+  illustrate the usage of various features.
+  </para>
+<!--
+  This is information on the sample application. It will be included
+  in the documentation (see doc/openjpa/samples-guide.xml). It will also
+  automatically be converted into a README.txt file in this directory
+  in the "release.org.apache.openjpa.releasedocs" build target phase of the release.
+-->
+      <section id="samples_guide_interop">
+        <title>JDO - JPA Persistence Interoperability</title>
+        <para>This sample demonstrates how to combine JDO and JPA in a single
+application. The <filename>MachineMain.java</filename> program uses both
+<classname>EntityManager</classname>s and <classname>PersistenceManager</classname>s 
+in a single transaction including persist, delete and query operations.</para>
+        <para>The sample includes both annotated persistent classes as well as JDOR 
+metadata information.  The application can switch to either system simply
+by changing the bootstrap mechanism.  Depending on which configuration
+system you use, OpenJPA will read the corresponding metadata format.  You can
+override some or all of this behavior using OpenJPA's configuration options, 
+such as <link linkend="openjpa.MetaDataFactory">openjpa.MetaDataFactory</link>.</para>
+        <para>To use this sample, you should ensure that either a <filename>jdo.properties</filename>
+or <filename>persistence.xml</filename> are in the <filename>META-INF</filename> directory 
+in your <envar>CLASSPATH</envar>. The rest of the files for this sample are located in the 
+<filename>samples/mixed</filename> directory of the OpenJPA installation.  This tutorial requires JDK 5.  
+To run this tutorial:</para>
+        <itemizedlist>
+          <listitem>
+            <para>Ensure that your environment is set properly as described in the
+  README and that your current path is in the mixed sample directory.</para>
+          </listitem>
+          <listitem>
+            <para>
+  You may want to edit <literal>ConnectionURL</literal> to point to an absolute 
+    URL (e.g. <filename>C:/openjpa/mixed-sample-db</filename>) if using a file-based database like 
+  <literal>HSQL</literal>.</para>
+          </listitem>
+          <listitem>
+            <para>Include the list of persistent classes in your configuration file.  For
+  JPA, you will want to add the following lines to 
+  <filename>persistence.xml</filename> before the <literal>&lt;property&gt;</literal> lines:
+  </para>
+            <programlisting format="linespecific">
+&lt;class&gt;samples.mixed.Machine&lt;/class&gt;
+&lt;class&gt;samples.mixed.Crane&lt;/class&gt;
+&lt;class&gt;samples.mixed.Bulldozer&lt;/class&gt;
+&lt;class&gt;samples.mixed.Operator&lt;/class&gt;
+</programlisting>
+            <para>
+  If you are using JDO, point the metadata factory at the <filename>.jdo</filename>
+resource containing your persistent classes:
+  </para>
+            <programlisting format="linespecific">
+openjpa.MetaDataFactory: Resources=samples/mixed/package.jdo
+</programlisting>
+          </listitem>
+          <listitem>
+            <para>Compile the classes:
+  
+  </para>
+            <para>
+              <userinput>javac *.java</userinput>
+            </para>
+          </listitem>
+          <listitem>
+            <para>You should then proceed to pass in the configuration file you are using
+  to the enhancer:
+
+  </para>
+            <para>
+              <userinput>openjpac -p persistence.xml Machine.java Crane.java Bulldozer.java Operator.java</userinput>
+            </para>
+            <para>
+    or
+  </para>
+            <para>
+              <userinput>jdoc -p jdo.properties Machine.java Crane.java Bulldozer.java Operator.java</userinput>
+            </para>
+          </listitem>
+          <listitem>
+            <para>Similarly, you should pass in the same argument to <literal>mappingtool</literal>:
+
+  </para>
+            <para>
+              <userinput>mappingtool -p persistence.xml -a buildSchema Machine.java Crane.java Bulldozer.java Operator.java</userinput>
+            </para>
+            <para>
+    or
+  </para>
+            <para>
+              <userinput>mappingtool -p jdo.properties -a buildSchema Machine.java Crane.java Bulldozer.java Operator.java</userinput>
+            </para>
+          </listitem>
+          <listitem>
+            <para>You can now run the sample application.  The first argument is
+  which operation you want the program to run.  The second argument tells 
+  the application which bootstrap system to use:
+
+  </para>
+            <para>
+              <userinput>java samples.mixed.MachineMain &lt;create | delete&gt; &lt;jdo | jpa&gt;</userinput>
+            </para>
+          </listitem>
+        </itemizedlist>
+      </section>
+      <section id="samples_guide_ejbdiv">
+        <title>JPA</title>
+<!--
+  This is information on the sample application. It will be included
+  in the documentation (see doc/openjpa/samples-guide.xml). It will also
+  automatically be converted into a README.txt file in this directory
+  in the "release.jdo.releasedocs" build target phase of the release.
+-->
+        <section id="samples_guide_model_humres_ejb">
+          <title>Sample Human Resources Model</title>
+          <para>The files for this sample are located in the <filename>samples/persistence/models/humres</filename> 
+directory of the OpenJPA installation.  This sample demonstrates the mapping of 
+an example "Human Resources" schema. The following concepts are illustrated
+in this sample:</para>
+          <itemizedlist>
+            <listitem>
+              <para>Value Mappings</para>
+            </listitem>
+            <listitem>
+              <para>One to One Mappings</para>
+            </listitem>
+            <listitem>
+              <para>One to Many Mappings (with and without inverses)</para>
+            </listitem>
+          </itemizedlist>
+        </section>
+      </section>
+    </chapter>



Mime
View raw message