You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by mp...@apache.org on 2006/08/22 23:28:55 UTC
svn commit: r433761 [9/18] - in /incubator/openjpa/trunk/openjpa-project: ./
src/doc/manual/
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/openjpa_intro.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/openjpa_intro.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/openjpa_intro.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/openjpa_intro.xml Tue Aug 22 14:28:53 2006
@@ -0,0 +1,61 @@
+
+ <chapter id="openjpa_intro">
+ <title>OpenJPA <phrase>JPA</phrase></title>
+ <indexterm zone="openjpa_intro">
+ <primary>OpenJPA <phrase>JPA</phrase></primary>
+ </indexterm>
+ <para>
+ OpenJPA is Apache's implementation of Sun's
+ <phrase>Java Persistence API (JPA) specification</phrase>
+
+
+ for the transparent persistence of Java objects.
+ This document provides an overview of
+ <phrase>the JPA standard</phrase>
+
+
+ and technical details on the use of OpenJPA <phrase>JPA</phrase>.
+ </para>
+ <para>
+ To quickly get started with JPA, you may want to begin at
+ <xref linkend="jpa_tutorial"/>.
+ If you would prefer to start with an introduction to the concepts of JPA,
+ begin with <xref linkend="jpa_overview_intro"/>.
+ </para>
+ <section id="openjpa_intro_about">
+ <title>About This Document</title>
+ <para>
+ This document is intended for OpenJPA users. It is divided into several
+ parts:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <link linkend="jpa_overview_intro">JPA Overview</link>
+ describes the fundamentals of JPA.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In the <link linkend="tutorials">OpenJPA <phrase>JPA</phrase>
+ Tutorials</link> you will develop simple persistent applications
+ using OpenJPA. Through the tutorials' hands-on approach, you
+ will become comfortable with the core tools and development
+ processes under OpenJPA <phrase>JPA</phrase>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <link linkend="ref_guide_intro">OpenJPA <phrase>JPA</phrase>
+ Reference Guide</link> contains detailed documentation on all
+ aspects of OpenJPA <phrase>JPA</phrase>. Browse through this guide to
+ familiarize yourself with the many advanced features and
+ customization opportunities OpenJPA provides. Later, you can use
+ the guide when you need details on a specific aspect of OpenJPA
+ <phrase>JPA</phrase>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+
+ </chapter>
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/ref_guide_caching.xml Tue Aug 22 14:28:53 2006
@@ -0,0 +1,1088 @@
+
+ <chapter id="ref_guide_caching">
+ <title>Caching</title>
+ <para>
+ OpenJPA utilizes several configurable caches to maximize performance.
+ This chapter explores OpenJPA's data cache, query cache, and query compilation
+ cache.
+ </para>
+ <section id="ref_guide_cache">
+ <title>Data Cache</title>
+ <indexterm zone="ref_guide_cache">
+ <primary>caching</primary>
+ <secondary>data cache</secondary>
+ </indexterm>
+ <para>
+ The OpenJPA data cache is an optional cache of persistent object data that
+ operates at the <classname>EntityManagerFactory</classname>
+ level. This cache is designed to significantly increase
+ performance while remaining in full compliance with the JPA
+ standard. This means that turning on the caching option can
+ transparently increase the performance of your application, with
+ no changes to your code.
+ </para>
+
+ <para>
+ OpenJPA's data cache is not related to the <classname>EntityManager
+ </classname> cache dictated by the JPA specification. The JPA
+ specification mandates behavior for the <classname>EntityManager</classname>
+ cache aimed at guaranteeing transaction isolation when operating on
+ persistent objects.
+ </para>
+ <para>
+ OpenJPA's data cache is designed to
+ provide significant performance increases over cacheless
+ operation, while guaranteeing that behavior will be
+ identical in both cache-enabled and cacheless operation.
+ </para>
+ <para>
+ There are five ways to access data via the OpenJPA APIs:
+ standard relation traversal, large result set relation traversal,
+ queries, looking up an object by id, and iteration over an
+ <classname>Extent</classname>. OpenJPA's cache plugin accelerates three of
+ these mechanisms. It does not provide any caching of large result set
+ relations or <classname>Extent</classname> iterators. If you find yourself
+ in need of higher-performance <classname>Extent</classname> iteration, see
+ <xref linkend="ref_guide_cache_limits_extent"/>.
+ <table><title>Data access methods</title><tgroup cols="2" align="left" colsep="1" rowsep="1"><colspec colname="access-method"/><colspec colname="cacheable"/><thead><row><entry colname="access-method">Access method</entry><entry colname="cacheable">Uses cache</entry></row></thead><tbody><row><entry colname="access-method">
+ Standard relation traversal
+ </entry><entry colname="cacheable">Yes</entry></row><row><entry colname="access-method">
+ Large result set relation traversal
+ </entry><entry colname="cacheable">No</entry></row><row><entry colname="access-method">Query</entry><entry colname="cacheable">Yes</entry></row><row><entry colname="access-method">
+ Lookups by object id
+ </entry><entry colname="cacheable">Yes</entry></row><row><entry colname="access-method">
+ Iteration over an <classname>Extent</classname>
+ </entry><entry colname="cacheable">No</entry></row></tbody></tgroup></table>
+ </para>
+ <para>
+ When enabled, the cache is checked before making a trip to the
+ datastore. Data is stored in the cache when objects are
+ committed and when persistent objects are loaded from the
+ datastore.
+ </para>
+ <para>
+ OpenJPA's data cache can in both single-JVM and multi-JVM environments.
+ Multi-JVM caching is achieved through the use of the distributed event
+ notification framework described in <xref linkend="ref_guide_event"/>,
+ or through one of OpenJPA's integrations with third-party distributed caches
+ (see <xref linkend="ref_guide_datacacheintegrations"/>).
+ </para>
+ <para>
+ The single JVM mode of operation maintains and shares a data
+ cache across all <classname>EntityManager</classname>
+ instances obtained from a particular
+ <classname>EntityManagerFactory</classname>. This is not
+ appropriate for use in a distributed environment, as caches in
+ different JVMs or created from different
+ <classname>EntityManagerFactory</classname> objects will
+ not be synchronized.
+ </para>
+ <section id="ref_guide_cache_conf">
+ <title>Data Cache Configuration</title>
+ <para>
+ To enable the basic single-factory cache set the
+ <link linkend="openjpa.DataCache"><literal>openjpa.DataCache</literal></link>
+ property to <literal>true</literal>, and set the
+ <link linkend="openjpa.RemoteCommitProvider"><literal>
+ openjpa.RemoteCommitProvider</literal></link> property to
+ <literal>sjvm</literal>:
+ </para>
+ <example id="ref_guide_cache_conf_sjvm">
+ <title>Single-JVM Data Cache</title>
+ <programlisting format="linespecific">
+<property name="openjpa.DataCache" value="true"/>
+<property name="openjpa.RemoteCommitProvider" value="sjvm"/>
+</programlisting>
+ </example>
+ <para>
+ To configure the data cache to remain up-to-date in a distributed
+ environment, set the <link linkend="openjpa.RemoteCommitProvider"><literal>
+ openjpa.RemoteCommitProvider</literal></link> property appropriately, or
+ integrate OpenJPA with a third-party caching solution.
+ Remote commit providers are described in
+ <xref linkend="ref_guide_event"/>.
+ <xref linkend="ref_guide_datacacheintegrations"/> enumerates supported
+ third-party caching solutions.
+ </para>
+ <para><indexterm><primary>caching</primary><secondary>size</secondary></indexterm>
+ OpenJPA's default implementation maintains a least-recently-used map
+ of object ids to cache data. By default,
+ 1000 elements are kept in cache. This can be adjusted by setting
+ the <literal>CacheSize</literal> property in your plugin string - see
+ below for an example. Objects that are pinned into the cache are not
+ counted when determining if the cache size exceeds the maximum.
+ </para>
+ <para>
+ Expired objects are moved to a soft reference map, so they may stick
+ around for a little while longer. You can control
+ the number of soft references OpenJPA keeps with the <literal>
+ SoftReferenceSize</literal> property. Soft references are unlimited by
+ default. Set to 0 to disable soft references completely.
+ </para>
+ <example id="ref_guide_cache_conf_size">
+ <title>Data Cache Size</title>
+ <programlisting format="linespecific">
+<property name="openjpa.DataCache" value="true(CacheSize=5000, SoftReferenceSize=0)"/>
+</programlisting>
+ </example>
+ <para><indexterm><primary>caching</primary><secondary>timeout</secondary></indexterm>
+ You can specify a cache timeout value for a class by setting the
+ timeout <link linkend="ref_guide_meta_ext">metadata extension</link>
+ to the amount of time in milliseconds a class's data is valid. Use a
+ value of -1 for no expiration. This is the default value.
+ </para>
+ <example id="ex_timeout_cache">
+ <title>Data Cache Timeout</title>
+ <para>
+ Timeout <classname>Employee</classname> objects after 10 seconds.
+ </para>
+ <programlisting format="linespecific">
+@Entity
+@DataCache(timeout=10000)
+public class Employee
+{
+ ...
+}
+</programlisting>
+ </example>
+ <para>
+ See the <ulink url="../apidocs/org/apache/openjpa/persistence/DataCache.html"><classname>org.apache.openjpa.persistence.DataCache</classname></ulink> Javadoc
+ for more information on the <classname>DataCache</classname> annotation.
+ </para>
+ <para><indexterm><primary>caching</primary><secondary>cron-style invalidation</secondary></indexterm>
+ A cache can specify that it should be cleared at certain times
+ rather than using data timeouts. The
+ <literal>EvictionSchedule</literal> property of OpenJPA's
+ cache implementation accepts a <literal>cron</literal>
+ style eviction schedule. The format of this property is a
+ whitespace-separated list of five tokens, where the
+ <literal>*</literal> symbol (asterisk), indicates match all. The
+ tokens are, in order:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Minute</para>
+ </listitem>
+ <listitem>
+ <para>Hour of Day</para>
+ </listitem>
+ <listitem>
+ <para>Day of Month</para>
+ </listitem>
+ <listitem>
+ <para>Month</para>
+ </listitem>
+ <listitem>
+ <para>Day of Week</para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ For example, the following <literal>openjpa.DataCache</literal> setting
+ schedules the default cache to evict values
+ from the cache at 15 and 45 minutes past 3 PM on Sunday.
+ </para>
+ <programlisting format="linespecific">
+true(EvictionSchedule='15,45 15 * * 1')
+</programlisting>
+ <para><indexterm><primary>caching</primary><secondary>named caches</secondary></indexterm>
+ It is also possible for different persistence-capable classes to use
+ different caches. This is achieved by specifying a cache name in
+ a <link linkend="ref_guide_meta_ext">metadata extension</link>.
+ </para>
+ <example id="ex_non_default_cache">
+ <title>Named Data Cache Specification</title>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+@Entity
+@DataCache(name="small-cache", timeout=10000)
+public class Employee
+{
+ ...
+}
+</programlisting>
+ </example>
+ <para>
+ See the <ulink url="../apidocs/org/apache/openjpa/persistence/DataCache.html"><classname>org.apache.openjpa.persistence.DataCache</classname></ulink> Javadoc
+ for more information on the <classname>DataCache</classname> annotation.
+ </para>
+ <para>
+ The metadata above will cause instances of the <classname>Employee
+ </classname> class to be stored in a cache named <literal>
+ small-cache</literal>.
+ This <literal>small-cache</literal> cache can be explicitly configured
+ in the <literal>openjpa.DataCache</literal> plugin string, or can be
+ implicitly defined, in which case it will take on the same
+ default configuration properties as the default cache identified
+ in the <literal>openjpa.DataCache</literal> property.
+ </para>
+ <example id="ref_guide_cache_named">
+ <title>Named Data Cache Configuration</title>
+ <programlisting format="linespecific">
+<property name="openjpa.DataCache" value="true, true(Name=small-cache, CacheSize=100)"/>
+</programlisting>
+ </example>
+ </section>
+ <section id="ref_guide_cache_use">
+ <title>Data Cache Usage</title>
+ <para>
+ The <literal>org.apache.openjpa.datacache</literal> package defines OpenJPA's
+ data caching framework. While you may use this framework directly
+ (see its <ulink url="../apidocs/org/apache/openjpa/datacache/package-summary.html">
+ Javadoc</ulink> for details), its APIs are meant primarily for
+ service providers. In fact, <xref linkend="ref_guide_cache_extension"/>
+ below has tips on how to use this package to extend OpenJPA's caching
+ service yourself.
+ </para>
+ <para>
+ Rather than use the low-level <literal>org.apache.openjpa.datacache</literal>
+ package APIs, JPA users should typically access the data
+ cache through OpenJPA's high-level
+ <ulink url="../../api/openjpa/persistence/StoreCache.html"><classname>org.apache.openjpa.persistence.StoreCache</classname></ulink> facade.
+ This facade has methods to pin and unpin records, evict data from the
+ cache, and more.
+ </para>
+ <programlisting format="linespecific">
+public StoreCache getStoreCache ();
+public StoreCache getStoreCache (String name);
+</programlisting>
+ <para>
+ You obtain the <classname>StoreCache</classname> through the
+ <methodname>OpenJPAEntityManagerFactory.getStoreCache</methodname> methods.
+ When you have multiple data caches configured as in the
+ <literal>small-cache</literal> example above, the <classname>
+ StoreCache</classname> can act as a unified facade over all your
+ caches. For every oid parameter to the <classname>StoreCache
+ </classname> methods, it determines the correct data cache for that
+ oid's corresponding persistent class, and dynamically delegates to
+ that cache.
+ </para>
+ <para>
+ If you know that you want to access a certain data cache and no others,
+ the <ulink url="../../api/openjpa/persistence/OpenJPAEntityManagerFactory.html"><methodname>OpenJPAEntityManagerFactory.getStoreCache(String name)
+ </methodname></ulink> method returns a <classname>StoreCache</classname>
+ interface to a particular named data cache.
+ </para>
+ <example id="ref_guide_cache_access_ejb">
+ <title>Accessing the StoreCache</title>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
+StoreCache cache = kemf.getStoreCache ();
+...
+StoreCache smallCache = kemf.getStoreCache ("small-cache");
+...
+</programlisting>
+ </example>
+ <programlisting format="linespecific">
+public void evict (Class cls, Object oid);
+public void evictAll ();
+public void evictAll (Class cls, Object... oids);
+public void evictAll (Class cls, Collection oids);
+</programlisting>
+ <para>
+ The <methodname>evict</methodname> methods tell the cache to release
+ data. Each method takes an entity class and one or more identity
+ values, and releases the cached data for the corresponding persistent
+ instances. The <methodname>evictAll</methodname> method with no
+ arguments clears the cache. Eviction is useful when the datastore is
+ changed by a separate process outside OpenJPA's control. In this
+ scenario, you typically
+ have to manually evict the data from the datastore cache; otherwise the
+ OpenJPA runtime, oblivious to the changes, will maintain its stale copy.
+ </para>
+ <programlisting format="linespecific">
+public void pin (Class cls, Object oid);
+public void pinAll (Class cls, Object... oids);
+public void pinAll (Class cls, Collection oids);
+public void unpin (Class cls, Object oid);
+public void unpinAll (Class cls, Object... oids);
+public void unpinAll (Class cls, Collection oids);
+</programlisting>
+ <para>
+ Most caches are of limited size. Pinning an identity to the cache
+ ensures that the cache will mill not kick the data for the corresponding
+ instance out of the cache, unless you manually evict it. Note that even
+ after manual eviction, the data will get pinned again the next time it
+ is fetched from the store. You can only remove a pin and make the data
+ once again available for normal cache overflow eviction through the
+ <methodname>unpin</methodname> methods. Use pinning when you want a
+ guarantee that a certain object will always be available from cache,
+ rather than requiring a datastore trip.
+ </para>
+ <example id="ref_guide_cache_use_ejb">
+ <title>StoreCache Usage</title>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
+StoreCache cache = kemf.getStoreCache ();
+cache.pin (Magazine.class, popularMag.getId ());
+cache.evict (Magazine.class, changedMag.getId ());
+</programlisting>
+ </example>
+ <para>
+ See the <classname>StoreCache</classname>
+ <ulink url="../../api/openjpa/persistence/StoreCache.html">Javadoc</ulink>
+ for information on additional functionality it provides.
+ Also, <xref linkend="ref_guide_runtime"/> discusses OpenJPA's other
+ extensions to the standard set of JPA runtime interfaces.
+ </para>
+ <para>
+ The examples above include calls to <methodname>evict</methodname> to
+ manually remove data from the data cache. Rather than evicting objects
+ from the data cache directly, you can also configure OpenJPA to
+ automatically evict objects from the data cache when
+ you use the <classname>OpenJPAEntityManager</classname>'s eviction APIs.
+ </para>
+ <example id="ref_guide_cache_pmevict">
+ <title>Automatic Data Cache Eviction</title>
+ <programlisting format="linespecific">
+<property name="openjpa.BrokerImpl" value="EvictFromDataCache=true"/>
+</programlisting>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+kem.evict (changedMag); // will evict from data cache also
+</programlisting>
+ </example>
+ </section>
+ <section id="ref_guide_cache_query">
+ <title>Query Cache</title>
+ <indexterm zone="ref_guide_cache_query">
+ <primary>caching</primary>
+ <secondary>query cache</secondary>
+ </indexterm>
+ <indexterm zone="ref_guide_cache_query">
+ <primary>Query</primary>
+ <secondary>result caching</secondary>
+ </indexterm>
+ <para>
+ In addition to the data cache, the <literal>org.apache.openjpa.datacache</literal>
+ package defines service provider interfaces for a query cache.
+ The query cache is enabled by default when the data cache
+ is enabled. The query cache stores the object ids returned by
+ query executions. When you run a query, OpenJPA assembles a key based on
+ the query properties and the parameters used at execution time,
+ and checks for a cached query result. If one is found, the
+ object ids in the cached result are looked up, and the resultant
+ persistence-capable objects are returned. Otherwise, the query
+ is executed against the database, and the object ids loaded by
+ the query are put into the cache. The object id list is not
+ cached until the list returned at query execution time is fully
+ traversed.
+ </para>
+ <para>
+ OpenJPA exposes a high-level interface to the query cache through
+ the <ulink url="../../api/openjpa/persistence/QueryResultCache.html"><classname>org.apache.openjpa.persistence.QueryResultCache</classname></ulink> class.
+ You can access this class through the <classname>
+ OpenJPAEntityManagerFactory</classname>.
+ </para>
+ <example id="ref_guide_cache_queryaccess">
+ <title>Accessing the QueryResultCache</title>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
+QueryResultCache qcache = kemf.getQueryResultCache ();
+</programlisting>
+ </example>
+ <para>
+ The default query cache implementation caches 100 query
+ executions in a least-recently-used cache. This can be changed
+ by setting the cache size in the <literal>CacheSize</literal>
+ plugin property. Like the data cache, the query cache also has a
+ backing soft reference map. The <literal>SoftReferenceSize</literal>
+ property controls the size of this map. It is disabled by default.
+ </para>
+ <example id="ref_guide_cache_cachesize">
+ <title>Query Cache Size</title>
+ <programlisting format="linespecific">
+<property name="openjpa.QueryCache" value="CacheSize=1000, SoftReferenceSize=100"/>
+</programlisting>
+ </example>
+ <para>
+ To disable the query cache completely, set the
+ <literal>openjpa.QueryCache</literal> property to <literal>false</literal>:
+ </para>
+ <example id="ref_guide_cache_disablequery">
+ <title>Disabling the Query Cache</title>
+ <programlisting format="linespecific">
+<property name="openjpa.QueryCache" value="false"/>
+</programlisting>
+ </example>
+ <para>
+ There are certain situations in which the query cache is bypassed:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Caching is not used for in-memory queries (queries in which
+ the candidates are a collection instead of a class or
+ <classname>Extent</classname>).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Caching is not used in transactions that have
+ <literal>IgnoreChanges</literal> set to <literal>false</literal>
+ and in which modifications to classes in the query's access
+ path have occurred. If none of the classes in the access path
+ have been touched, then cached results are still valid and
+ are used.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Caching is not used in pessimistic transactions, since OpenJPA
+ must go to the database to lock the appropriate rows.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Caching is not used when the the data cache does not have any
+ cached data for an id in a query result.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Queries that use persistence-capable objects as parameters are
+ only cached if the parameter is directly compared to field,
+ as in:
+ </para>
+ <programlisting format="linespecific">
+select e from Employee e where e.company.address = :addr
+</programlisting>
+ <para>
+ If you extract field values from the parameter in your query
+ string, or if the parameter is used in collection element
+ comparisons, the query is not cached.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Queries that result in projections of custom field types or
+ <classname>BigDecimal</classname> or
+ <classname>BigInteger</classname> fields are not cached.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Cache results are removed from the cache when instances of
+ classes in a cached query's access path are touched. That is, if
+ a query accesses data in class <classname>A</classname>, and instances
+ of class <classname>A</classname> are modified, deleted, or inserted,
+ then the cached query result is dropped from the cache.
+ </para>
+ <para>
+ It is possible to tell the query cache that a class has been altered.
+ This is only necessary when the changes occur via direct modification
+ of the database outside of OpenJPA's control. You can also evict
+ individual queries, or clear the entire cache.
+ </para>
+ <programlisting format="linespecific">
+public void evict (Query q);
+public void evictAll (Class cls);
+public void evictAll ();
+</programlisting>
+ <para>
+ For JPA queries with parameters, set the desired parameter values
+ into the <ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html"><classname>Query</classname></ulink> instance before calling the
+ above methods.
+ </para>
+ <example id="ref_guide_cache_query_classchange">
+ <title>Evicting Queries</title>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
+QueryResultCache qcache = kemf.getQueryResultCache ();
+
+// evict all queries that can be affected by changes to Magazines
+qcache.evictAll (Magazine.class);
+
+// evict an individual query with parameters
+EntityManager em = emf.createEntityManager ();
+Query q = em.createQuery (...).
+ setParameter (0, paramVal0).
+ setParameter (1, paramVal1);
+qcache.evict (q);
+</programlisting>
+ </example>
+ <para>
+ When using one of OpenJPA's distributed cache implementations, it is
+ necessary to perform this in every JVM - the change notification is
+ not propagated automatically. When using a coherent cache
+ implementation such as OpenJPA's Tangosol cache implementation, it is not
+ necessary to do this in every JVM (although it won't hurt to do so),
+ as the cache results are stored directly in the coherent cache.
+ </para>
+ <para>
+ Queries can also be pinned and unpinned
+ through the <classname>QueryResultCache</classname>. The semantics of
+ these operations are the same as pinning and unpinning data from the
+ data cache.
+ </para>
+ <programlisting format="linespecific">
+public void pin (Query q);
+public void unpin (Query q);
+</programlisting>
+ <para>
+ For JPA queries with parameters, set the desired parameter values
+ into the <ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/Query.html"><classname>Query</classname></ulink> instance before calling the
+ above methods.
+ </para>
+ <para>
+ The following example shows these APIs in action.
+ </para>
+ <example id="ref_guide_cache_query_pin">
+ <title>Pinning, and Unpinning Query Results</title>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
+QueryResultCache qcache = kemf.getQueryResultCache ();
+EntityManager em = emf.createEntityManager ();
+
+Query pinQuery = em.createQuery (...).
+ setParameter (0, paramVal0).
+ setParameter (1, paramVal1);
+qcache.pin (pinQuery);
+Query unpinQuery = em.createQuery (...).
+ setParameter (0, paramVal0).
+ setParameter (1, paramVal1);
+qcache.unpin (unpinQuery);
+</programlisting>
+ </example>
+ <para>
+ Pinning data into the cache instructs the cache to not expire the
+ pinned results when cache flushing occurs. However, pinned results
+ will be removed from the cache if an event occurs that invalidates the
+ results.
+ </para>
+<!--
+ ### known issues:
+ - timeouts of query cache data based on access path timeouts
+ - distributed cache
+ - fire class change notifications
+ - tangosol
+ - either fire ccn's or store queries in cache
+ - access path
+ -->
+ <para>
+ You can disable caching on a per-<classname>EntityManager
+ </classname> or per-<classname>Query</classname> basis:
+ </para>
+ <example id="ref_guide_cache_query_disable">
+ <title>Disabling and Enabling Query Caching</title>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+// temporarily disable query caching for all queries created from em
+OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+kem.getFetchPlan ().setQueryResultCache (false);
+
+// re-enable caching for a particular query
+OpenJPAQuery kq = kem.createQuery (...);
+kq.getFetchPlan ().setQueryResultCache (true);
+</programlisting>
+ <programlisting format="linespecific">
+import org.apache.openjpa.jdo.*;
+
+...
+
+// temporarily disable query caching for all queries created from pm
+PersistenceManager pm = ...;
+OpenJPAFetchPlan fetch = (OpenJPAFetchPlan) pm.getFetchPlan ();
+fetch.setQueryResultCache (false);
+
+// re-enable caching for a particular query
+Query q = pm.newQuery (...);
+OpenJPAFetchPlan fetch = OpenJPAJDOHelper.cast (pm.getFetchPlan ());
+fetch.setQueryResultCache (true);
+</programlisting>
+ </example>
+ </section>
+ <section id="ref_guide_cache_concurrent">
+ <title>The Concurrent Data Cache</title>
+ <para>
+ The <emphasis>concurrent</emphasis> is a new data cache plugin for OpenJPA.
+ It has not been as thoroughly tested as OpenJPA's standard data cache.
+ The concurrent cache can, however, offer considerably greater
+ performance and scalability characteristics compared to the standard
+ cache when the following conditions are met:
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ The cache is big enough to hold all of your commonly-used data.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Your application is heavily concurrent.
+ </para>
+ </listitem>
+ </orderedlist>
+ <para>
+ Additionally, this cache does not fully index its contents by class,
+ but rather just keeps track of which clasess are in the cache. It
+ services requests to drop given classes by checking to see if any
+ instances of that class might be in the cache, and then clearing the
+ entire cache. This inefficiency can easily be worked around with careful
+ cache partitioning.
+ </para>
+ <para>
+ To use the concurrent data cache instead of the standard data cache,
+ set your <literal>openjpa.DataCache</literal> property to
+ <literal>concurrent</literal> instead of <literal>true</literal>.
+ Or, you can mix concurrent and standard caches in a set of named
+ caches.
+ </para>
+ <para>
+ The concurrent cache has the following configuration parameters:
+ </para>
+ <orderedlist>
+ <listitem>
+ <para><literal>CacheSize</literal>: The maximum number of
+ objects that this cache will hold. The default is 1000 objects.
+ This setting differs from the setting for the default data cache
+ in that instances that are pinned into cache do count towards
+ this limit.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>Name</literal>: The unique name of the cache.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>EvictionSchedule</literal>: A cron-style eviction
+ schedule that this cache should follow.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>LRUThresholdRatio</literal>: The ratio above which
+ this implementation should start applying its
+ least-recently-used algorithm to prepare for eviction should
+ the need arise. Default is 80%. Values should be integers
+ between 1 and 100.
+ </para>
+ </listitem>
+ </orderedlist>
+ <example id="ref_guide_cache_concurrent_conf">
+ <title>Concurrent Data Cache Configuration</title>
+ <para>
+ The following configuration uses the standard OpenJPA cache as the
+ primary cache and a named concurrent cache as a secondary cache.
+ Various classes can be configured to use this secondary cache in
+ their metadata.
+ </para>
+ <programlisting format="linespecific">
+<property name="openjpa.DataCache" value="true, concurrent(Name=secondary)"/>
+</programlisting>
+ </example>
+ </section>
+ <section id="ref_guide_datacacheintegrations">
+ <title>Third-Party Integrations</title>
+ <para>
+ OpenJPA includes built-in integrations with Tangosol Coherence and
+ GemStone GemFire caching products.
+ </para>
+ <section id="ref_guide_cache_tangosol">
+ <title>Tangosol Integration</title>
+ <indexterm zone="ref_guide_cache_tangosol">
+ <primary>caching</primary>
+ <secondary>tangosol integration</secondary>
+ </indexterm>
+ <para>
+ The OpenJPA data cache can integrate with Tangosol's Coherence caching
+ system. To use Tangosol integration, set the
+ <link linkend="openjpa.DataCache"><literal>openjpa.DataCache</literal></link> configuration property to <literal>tangosol</literal>, with
+ the appropriate plugin properties for your Tangosol setup. For
+ example:
+ </para>
+ <example id="ref_guide_cache_tangosol_conf">
+ <title>Tangosol Cache Configuration</title>
+ <programlisting format="linespecific">
+<property name="openjpa.DataCache" value="tangosol(TangosolCacheName=openjpa)"/>
+</programlisting>
+ </example>
+ <para>
+ The Tangosol cache understands the following properties:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>TangosolCacheName</literal>: The name of the
+ Tangosol Coherence cache to use. Defaults to
+ <literal>openjpa</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>TangosolCacheType</literal>: The type of Tangosol
+ Coherence cache to use (optional). Valid values are
+ <literal>named</literal>, <literal>distributed</literal>, or
+ <literal>replicated</literal>. Defaults to <literal>
+ named</literal>, which means that the cache is looked
+ up via the <literal>
+ com.tangosol.net.CacheFactory.getCache(String)</literal>
+ method. This method looks up the cached by name as
+ defined in the Coherence configuration.
+ </para>
+ <note>
+ <para>
+ As of this writing, it is not possible to use a Tangosol
+ Coherence 1.2.2 distributed cache type with Apple's OS X
+ 1.3.1 JVM. Use their replicated cache instead.
+ </para>
+ </note>
+ </listitem>
+ <listitem>
+ <para><literal>ClearOnClose</literal>: Whether the Tangosol
+ named cache should be completely cleared when the
+ <phrase><classname>EntityManagerFactory</classname></phrase>
+
+
+ is closed. Defaults to <literal>false</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The OpenJPA query cache can also integrate with Tangosol's Coherence
+ caching system. To use Tangosol query cache integration, set the
+ <link linkend="openjpa.QueryCache"><literal>openjpa.QueryCache</literal></link> configuration property to <literal>tangosol</literal>,
+ with the appropriate plugin properties for your Tangosol setup.
+ For example:
+ </para>
+ <example id="ref_guide_cache_tangosol_query_conf">
+ <title>Tangosol Query Cache Configuration</title>
+ <programlisting format="linespecific">
+<property name="openjpa.QueryCache" value="tangosol(TangosolCacheName=openjpa-query)"/>
+</programlisting>
+ </example>
+ <para>
+ The Tangosol query cache understands the same properties as the
+ data cache, with a default Tangosol cache name of
+ <literal>openjpa-query</literal>.
+ </para>
+ </section>
+ <section id="ref_guide_cache_gemfire">
+ <title>GemStone GemFire Integration</title>
+ <para>
+ The OpenJPA data cache can integrate with GemStone's GemFire v3.5.1
+ caching system.
+ later. To use GemFire in OpenJPA you will need to change your
+ <literal>gemfire.properties</literal> to have the property
+ <literal>enable-shared-memory=true</literal>. You will also need
+ to add both OpenJPA and GemFire to your classpath and then start
+ a GemFire server.
+ </para>
+ <programlisting format="linespecific">
+prompt> gemfire start
+</programlisting>
+ <para>
+ By default, the GemFire data cache will use a GemFire region of
+ <literal>root/openjpa-data-cache</literal> and the GemFire query cache
+ will use a region of <literal>root/openjpa-query-cache</literal>. This
+ can be changed be setting the optional property
+ <literal>GemFireCacheName</literal>.
+ </para>
+ <example id="ref_guide_datacacheintegrations_gemfire_conf">
+ <title>GemFire Cache Configuration</title>
+ <para><filename>persistence.xml</filename>:
+ </para>
+ <programlisting format="linespecific">
+<property name="openjpa.DataCache"
+ value="gemfire(GemFireCacheName=/root/my-openjpa-data-cache)"/>
+<property name="openjpa.QueryCache"
+ value="gemfire(GemFireCacheName=/root/my-openjpa-query-cache)"/>
+</programlisting>
+ <para>GemFire <filename>cache.xml</filename>:</para>
+ <programlisting format="linespecific">
+...
+ <shared-root-region name="root">
+ <region-attributes>
+ ...
+ </region-attributes>
+ <region name="My-openjpa-data-cache">
+ <region-attributes>
+ </region-attributes>
+ </region>
+ <region name="My-openjpa-query-cache">
+ <region-attributes>
+ </region-attributes>
+ </region>
+ </shared-root-region>
+ ...
+</programlisting>
+ </example>
+ <para>
+ If you set GemFire for both <literal>openjpa.DataCache</literal> and
+ <literal>openjpa.QueryCache</literal> you aren't required to
+ specify a <literal>openjpa.RemoteCommitProvider</literal> unless you
+ are registering your own <classname>
+ RemoteCommitListener</classname>s.
+ </para>
+ <para>
+ Some notes regarding using GemFire with OpenJPA:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Custom field types mapped with externalizers or custom
+ mappings must be serializable.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <link linkend="openjpa.DynamicDataStructs"><literal>
+ openjpa.DynamicDataStructs</literal></link> option
+ is not supported.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="ref_guide_cache_extension">
+ <title>Cache Extension</title>
+ <indexterm zone="ref_guide_cache_extension">
+ <primary>caching</primary>
+ <secondary>data cache</secondary>
+ <tertiary>extension</tertiary>
+ </indexterm>
+ <indexterm zone="ref_guide_cache_extension">
+ <primary>caching</primary>
+ <secondary>query cache</secondary>
+ <tertiary>extension</tertiary>
+ </indexterm>
+ <para>
+ The provided data cache classes can be easily extended to
+ add additional functionality. If you are adding new behavior,
+ you should extend <classname>org.apache.openjpa.datacache.DataCacheImpl</classname>.
+ To use your own storage mechanism, extend
+ <classname>org.apache.openjpa.datacache.AbstractDataCache</classname>, or implement
+ <classname>org.apache.openjpa.datacache.DataCache</classname> directly.
+ If you want to implement a distributed cache that uses an
+ unsupported method for communications, create an implementation
+ of <classname>org.apache.openjpa.event.RemoteCommitProvider</classname>. This
+ process is described in greater detail in
+ <xref linkend="ref_guide_event_customization"/>.
+ </para>
+ <para>
+ The query cache is just as easy to extend. Add functionality by
+ extending the default
+ <classname>org.apache.openjpa.datacache.QueryCacheImpl</classname>. Implement your
+ own storage mechanism for query results by extending
+ <classname>org.apache.openjpa.datacache.AbstractQueryCache</classname> or implementing
+ the <classname>org.apache.openjpa.datacache.QueryCache</classname> interface directly.
+ </para>
+ </section>
+ <section id="ref_guide_cache_notes">
+ <title>Important Notes</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The default cache implementations <emphasis>do not</emphasis>
+ automatically refresh objects in other <classname>
+ EntityManager</classname>s
+ when the cache is updated or invalidated. This behavior would
+ not be compliant with the JPA specification.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Invoking <methodname>OpenJPAEntityManager.evict</methodname>
+ <emphasis>does not</emphasis> result in
+ the corresponding data being dropped from the data cache, unless
+ you have set the proper configuration options as explained
+ above (see <xref linkend="ref_guide_cache_pmevict"/>). Other
+ methods related to the <classname>EntityManager</classname>
+ cache also do not effect the data cache.
+ </para>
+ <para>
+ The data cache
+ assumes that it is up-to-date with respect to the datastore,
+ so it is effectively an in-memory extension of the database. To
+ manipulate the data cache, you should generally use the data
+ cache facades presented in this chapter.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ You must specify a <classname>org.apache.openjpa.event.RemoteCommitProvider
+ </classname> (via the <link linkend="openjpa.RemoteCommitProvider"><literal>openjpa.RemoteCommitProvider</literal></link>
+ property) in order to use the data cache, even when using the
+ cache in a single-JVM mode. When using it in a single-JVM
+ context, set this property to <literal>sjvm</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="datastore_cache_issues">
+ <title>Known Issues and Limitations</title>
+ <indexterm zone="datastore_cache_issues">
+ <primary>caching</primary>
+ <secondary>issues and limitations</secondary>
+ </indexterm>
+ <itemizedlist>
+ <listitem>
+ <para>
+ When using datastore (pessimistic) transactions in concert
+ with the distributed caching implementations, it is possible
+ to read stale data when reading data outside a transaction.
+ </para>
+ <para>
+ For example, if you have two JVMs (JVM A and JVM B) both
+ communicating with each other, and JVM A obtains a data
+ store lock on a particular object's underlying data, it is
+ possible for JVM B to load the data from the cache without
+ going to the datastore, and therefore load data that should
+ be locked. This will only happen if JVM B attempts to read
+ data that is already in its cache during the period between
+ when JVM A locked the data and JVM B received and processed
+ the invalidation notification.
+ </para>
+ <para>
+ This problem is impossible to solve without putting together a
+ two-phase commit system for cache notifications, which would
+ add significant overhead to the caching implementation. As a
+ result, we recommend that people use optimistic locking when
+ using data caching. If you do not, then understand that some
+ of your non-transactional data may not be consistent with the
+ datastore.
+ </para>
+ <para>
+ Note that when loading objects in a transaction, the
+ appropriate datastore transactions will be obtained. So,
+ transactional code will maintain its integrity.
+ </para>
+ </listitem>
+ <listitem>
+ <para><classname>Extent</classname>s are not cached. So, if you plan
+ on iterating over a list of all the objects in an
+ <classname>Extent</classname> on a regular basis, you will
+ only benefit from caching if you do so with a
+ <classname>Query</classname> instead:
+ </para>
+ <example id="ref_guide_cache_limits_extent">
+ <title>Query Replaces Extent</title>
+ <programlisting format="linespecific">
+import org.apache.openjpa.persistence.*;
+
+...
+
+OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
+Extent extent = kem.getExtent (Magazine.class, false);
+
+// This iterator does not benefit from caching...
+Iterator uncachedIterator = extent.iterator ();
+
+// ... but this one does.
+OpenJPAQuery extentQuery = kem.createQuery (...);
+extentQuery.setSubclasses (false);
+Iterator cachedIterator = extentQuery.getResultList ().iterator ();
+</programlisting>
+ </example>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="ref_guide_cache_querycomp">
+ <title>Query Compilation Cache</title>
+ <indexterm zone="ref_guide_cache_querycomp">
+ <primary>caching</primary>
+ <secondary>query compilation cache</secondary>
+ </indexterm>
+ <para>
+ The query compilation cache is a <classname>Map</classname> used to
+ cache parsed query strings. As a result, most queries are
+ only parsed once in OpenJPA, and cached thereafter. You can control the
+ compilation cache through the
+ <link linkend="openjpa.QueryCompilationCache"><literal>
+ openjpa.QueryCompilationCache</literal></link> configuration property.
+ This property accepts a plugin string (see
+ <xref linkend="ref_guide_conf_plugins"/>) describing the
+ <classname>Map</classname> used to associate query strings and their
+ parsed form. This property accepts the following aliases:
+ </para>
+ <table>
+ <title>Pre-defined aliases</title>
+ <tgroup cols="2" align="left" colsep="1" rowsep="1">
+ <colspec colname="alias"/>
+ <colspec colname="value"/>
+ <colspec colname="notes"/>
+ <thead>
+ <row>
+ <entry colname="alias">Alias</entry>
+ <entry colname="value">Value</entry>
+ <entry colname="notes">Notes</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry colname="alias">
+ <literal>true</literal>
+ </entry>
+ <entry colname="value">
+ <literal>openjpa.util.CacheMap</literal>
+ </entry>
+ <entry colname="notes">
+ The default option. Uses a
+ <ulink url="../apidocs/org/apache/openjpa/util/CacheMap.html"><literal>CacheMap</literal></ulink> to store
+ compilation data. <literal>CacheMap</literal> uses
+ a least-recently-used strategy for a fixed number
+ of cache entries, and an optional soft reference
+ map for entries that are moved out of the LRU
+ space. So, for applications that have a
+ monotonically increasing number of distinct queries,
+ this option can be used to ensure that a fixed
+ amount of memory is used by the cache.
+ </entry>
+ </row>
+ <row>
+ <entry colname="alias">
+ <literal>all</literal>
+ </entry>
+ <entry colname="value">
+ <literal>java.util.HashMap</literal>
+ </entry>
+ <entry colname="notes">
+ This is the fastest option, but compilation data is
+ never dropped from the cache, so if you use a large
+ number of dynamic queries, this option may result in
+ ever-increasing memory usage. Note that if your
+ queries only differ in the values of the parameters,
+ this should not be an issue.
+ </entry>
+ </row>
+ <row>
+ <entry colname="alias">
+ <literal>false</literal>
+ </entry>
+ <entry colname="value">
+ <emphasis>none</emphasis>
+ </entry>
+ <entry colname="notes">
+ Disables the compilation cache.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ </chapter>