You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by aw...@apache.org on 2006/08/24 22:41:14 UTC
svn commit: r434517 [22/23] - in /incubator/openjpa/trunk:
openjpa-kernel/src/main/java/org/apache/openjpa/meta/
openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/
openjpa-project/src/doc/manual/
Modified: 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=434517&r1=434516&r2=434517&view=diff
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml (original)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_runtime.xml Thu Aug 24 13:41:12 2006
@@ -1,227 +1,291 @@
-
- <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>
+<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>
+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>
+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>
+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>
+ <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>
+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">
+ <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>
<property name="openjpa.BrokerImpl" value="EvictFromDataCache=true"/>
</programlisting>
- </example>
+ </example>
</section>
- </section>
- <section id="ref_guide_runtime_ejb">
- <title>JPA Extensions</title>
+ </section>
+ <section id="ref_guide_runtime_jpa">
+ <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>
+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">
+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>
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>
+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>
+ <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">
+ <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_jpaquery">
+ <title>
+ OpenJPAQuery
+ </title>
+ <indexterm zone="ref_guide_runtime_jpaquery">
+ <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_jpaquery">
+ <title>
+ Extent
+ </title>
+ <indexterm zone="ref_guide_runtime_jpaquery">
+ <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_jpaextentex">
+ <title>
+ Using a JPA Extent
+ </title>
+<programlisting>
import org.apache.openjpa.persistence.*;
...
@@ -231,166 +295,226 @@
for (Magazine m : mags)
processMagazine (m);
</programlisting>
- </example>
+ </example>
+ </section>
+ <section id="ref_guide_runtime_jpacache">
+ <title>
+ StoreCache
+ </title>
+ <indexterm zone="ref_guide_runtime_jpacache">
+ <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"></xref> has detailed information on OpenJPA's
+data caching system, including the <classname>StoreCache</classname> facade.
+ </para>
+ </section>
+ <section id="ref_guide_runtime_jpaquerycache">
+ <title>
+ QueryResultCache
+ </title>
+ <indexterm zone="ref_guide_runtime_jpaquerycache">
+ <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"></xref> for details on query caching in
+OpenJPA.
+ </para>
</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 id="ref_guide_runtime_jpafetch">
+ <title>
+ FetchPlan
+ </title>
+ <indexterm zone="ref_guide_runtime_jpafetch">
+ <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"></xref> ), 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"></xref> 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>
+ <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>
+ <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>
+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">
+ <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>
<property name="openjpa.ReadLockLevel" value="none"/>
<property name="openjpa.WriteLockLevel" value="write"/>
<property name="openjpa.LockTimeout" value="30000"/>
</programlisting>
- </example>
+ </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">
+ <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>
public LockModeType getReadLockMode ();
public FetchPlan setReadLockMode (LockModeType mode);
public LockModeType getWriteLockMode ();
@@ -398,15 +522,17 @@
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">
+ <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>
import org.apache.openjpa.persistence.*;
...
@@ -431,32 +557,40 @@
stock.setPrice (market.calculatePrice (stock));
em.getTransaction ().commit ();
</programlisting>
- </example>
+ </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">
+ <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>
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">
+ <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>
public void lock (Object pc);
public void lock (Object pc, LockModeType mode, long timeout);
public void lockAll (Object... pcs);
@@ -464,14 +598,15 @@
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">
+ <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>
import org.apache.openjpa.persistence.*;
// retrieve the lock level of an object
@@ -491,288 +626,306 @@
kem.getTransaction ().commit ();
</programlisting>
- </example>
+ </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">
+ <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>
<property name="openjpa.LockManager" value="pessimistic(VersionCheckOnReadLock=true,VersionUpdateOnWriteLock=true)"/>
</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">
+ </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>
<property name="openjpa.LockManager" value="none"/>
</programlisting>
- </example>
+ </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>
+ <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>
+ <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>
+ </section>
+ <section id="ref_guide_savepoints">
+ <title>
+ Savepoints
+ </title>
<indexterm zone="ref_guide_savepoints">
- <primary>savepoint</primary>
+ <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>
+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">
+ <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>
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">
+ <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>
import org.apache.openjpa.persistence.*;
...
@@ -798,274 +951,356 @@
// the price is now restored to mag.getPageCount () * pricePerPage
kem.getTransaction ().commit ();
</programlisting>
- </example>
+ </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>
+ <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>
+ </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>
+ <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 -->
+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>
+ <!-- ### -->
<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>
+ <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">
+ <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>
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">
+ </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>
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>
+ </example>
<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">
+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>
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">
+ </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>
select p from Product p where p.price < 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>
[... 985 lines stripped ...]