Doc corrections.

git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@452672 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
A. Abram White 2006-10-03 23:00:18 +00:00
parent 174ae93d41
commit afe9acd576
9 changed files with 707 additions and 1603 deletions

View File

@ -333,9 +333,9 @@ public class QueryImpl
}
public OpenJPAQuery setHint(String key, Object value) {
if (key == null || !key.startsWith("org.apache.openjpa."))
if (key == null || !key.startsWith("openjpa."))
return this;
String k = key.substring("org.apache.openjpa.".length());
String k = key.substring("openjpa.".length());
try {
if ("Subclasses".equals(k)) {

View File

@ -16,18 +16,13 @@ EJB 3 JSR page</ulink>
</listitem>
<listitem>
<para>
<ulink url="http://java.sun.com/javaee/5/docs/api/index.html">Locally mirrored
<ulink url="http://java.sun.com/javaee/5/docs/api/index.html">
javax.persistence Javadoc</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="../apidocs/index.html">OpenJPA API Javadoc</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="../apidocs/index.html">Full OpenJPA Javadoc</ulink>
<ulink url="../apidocs/index.html">OpenJPA Javadoc</ulink>
</para>
</listitem>
<listitem>

View File

@ -44,21 +44,54 @@ 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>
see <xref linkend="ref_guide_cache_limits_extent"/>.
</para>
<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>
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
@ -68,8 +101,7 @@ are loaded from the datastore.
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"/> ).
through custom integrations with a third-party distributed cache.
</para>
<para>
The single JVM mode of operation maintains and shares a data cache across all
@ -105,8 +137,6 @@ 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>
@ -117,16 +147,17 @@ third-party caching solutions.
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
OpenJPA's default implementation maintains a map of object
ids to cache data. By default, 1000 elements are kept in cache. When the cache
overflows, random entries are evicted. The maximum cache size 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.
not counted when determining if the cache size exceeds its maximum size.
</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
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">
@ -161,8 +192,7 @@ Timeout <classname>Employee</classname> objects after 10 seconds.
<programlisting>
@Entity
@DataCache(timeout=10000)
public class Employee
{
public class Employee {
...
}
</programlisting>
@ -223,56 +253,6 @@ past 3 PM on Sunday.
<programlisting>
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>
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>
&lt;property name="openjpa.DataCache" value="true, true(Name=small-cache, CacheSize=100)"/&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_cache_use">
<title>
@ -296,24 +276,11 @@ This facade has methods to pin and unpin records, evict data from the cache, and
more.
</para>
<programlisting>
public StoreCache getStoreCache ();
public StoreCache getStoreCache (String name);
public StoreCache getStoreCache();
</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="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.html">
<methodname>OpenJPAEntityManagerFactory.getStoreCache(String name)</methodname>
</ulink> method returns a <classname>StoreCache</classname> interface to a
particular named data cache.
OpenJPAEntityManagerFactory.getStoreCache</methodname> method.
</para>
<example id="ref_guide_cache_access_jpa">
<title>
@ -324,18 +291,16 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
StoreCache cache = kemf.getStoreCache ();
...
StoreCache smallCache = kemf.getStoreCache ("small-cache");
OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
StoreCache cache = oemf.getStoreCache();
...
</programlisting>
</example>
<programlisting>
public void evict (Class cls, Object oid);
public void evictAll ();
public void evictAll (Class cls, Object... oids);
public void evictAll (Class cls, Collection oids);
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
@ -348,12 +313,12 @@ the datastore cache; otherwise the OpenJPA runtime, oblivious to the changes,
will maintain its stale copy.
</para>
<programlisting>
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);
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
@ -374,10 +339,10 @@ 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 ());
OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
StoreCache cache = oemf.getStoreCache();
cache.pin(Magazine.class, popularMag.getId());
cache.evict(Magazine.class, changedMag.getId());
</programlisting>
</example>
<para>
@ -391,8 +356,8 @@ to the standard set of JPA runtime interfaces.
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.
from the data cache when you use the <classname>
OpenJPAEntityManager</classname>'s eviction APIs.
</para>
<example id="ref_guide_cache_pmevict">
<title>
@ -406,8 +371,8 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
kem.evict (changedMag); // will evict from data cache also
OpenJPAEntityManager oem = OpenJPAPersistence.cast(em);
oem.evict(changedMag); // will evict from data cache also
</programlisting>
</example>
</section>
@ -460,8 +425,8 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
QueryResultCache qcache = kemf.getQueryResultCache ();
OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
QueryResultCache qcache = oemf.getQueryResultCache();
</programlisting>
</example>
<para>
@ -498,7 +463,7 @@ There are certain situations in which the query cache is bypassed:
<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> ).
collection instead of a class or <classname>Extent</classname>).
</para>
</listitem>
<listitem>
@ -556,9 +521,9 @@ outside of OpenJPA's control. You can also evict individual queries, or clear
the entire cache.
</para>
<programlisting>
public void evict (Query q);
public void evictAll (Class cls);
public void evictAll ();
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
@ -574,17 +539,17 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
QueryResultCache qcache = kemf.getQueryResultCache ();
OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
QueryResultCache qcache = oemf.getQueryResultCache();
// evict all queries that can be affected by changes to Magazines
qcache.evictAll (Magazine.class);
qcache.evictAll(Magazine.class);
// evict an individual query with parameters
EntityManager em = emf.createEntityManager ();
Query q = em.createQuery (...).
setParameter (0, paramVal0).
setParameter (1, paramVal1);
EntityManager em = emf.createEntityManager();
Query q = em.createQuery(...).
setParameter(0, paramVal0).
setParameter(1, paramVal1);
qcache.evict (q);
</programlisting>
</example>
@ -597,13 +562,13 @@ Tangosol cache implementation, it is not necessary to do this in every JVM
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.
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>
public void pin (Query q);
public void unpin (Query q);
public void pin(Query q);
public void unpin(Query q);
</programlisting>
<para>
For JPA queries with parameters, set the desired parameter values into the
@ -622,18 +587,18 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManagerFactory kemf = OpenJPAPersistence.cast (emf);
QueryResultCache qcache = kemf.getQueryResultCache ();
EntityManager em = emf.createEntityManager ();
OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
QueryResultCache qcache = oemf.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);
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>
@ -642,8 +607,8 @@ when cache flushing occurs. However, pinned results will be removed from the
cache if an event occurs that invalidates the results.
</para>
<para>
You can disable caching on a per- <classname>EntityManager</classname> or per-
<classname>Query</classname> basis:
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>
@ -655,281 +620,15 @@ import org.apache.openjpa.persistence.*;
...
// temporarily disable query caching for all queries created from em
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
kem.getFetchPlan ().setQueryResultCache (false);
OpenJPAEntityManager oem = OpenJPAPersistence.cast(em);
oem.getFetchPlan ().setQueryResultCache(false);
// re-enable caching for a particular query
OpenJPAQuery kq = kem.createQuery (...);
kq.getFetchPlan ().setQueryResultCache (true);
</programlisting>
<programlisting>
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);
OpenJPAQuery oq = oem.createQuery(...);
oq.getFetchPlan().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>
&lt;property name="openjpa.DataCache" value="true, concurrent(Name=secondary)"/&gt;
</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>
&lt;property name="openjpa.DataCache" value="tangosol(TangosolCacheName=openjpa)"/&gt;
</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 <classname>EntityManagerFactory</classname>
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>
&lt;property name="openjpa.QueryCache" value="tangosol(TangosolCacheName=openjpa-query)"/&gt;
</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>
prompt&gt; 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>
&lt;property name="openjpa.DataCache"
value="gemfire(GemFireCacheName=/root/my-openjpa-data-cache)"/&gt;
&lt;property name="openjpa.QueryCache"
value="gemfire(GemFireCacheName=/root/my-openjpa-query-cache)"/&gt;
</programlisting>
<para>
GemFire <filename>cache.xml</filename>:
</para>
<programlisting>
...
&lt;shared-root-region name="root"&gt;
&lt;region-attributes&gt;
...
&lt;/region-attributes&gt;
&lt;region name="My-openjpa-data-cache"&gt;
&lt;region-attributes&gt;
&lt;/region-attributes&gt;
&lt;/region&gt;
&lt;region name="My-openjpa-query-cache"&gt;
&lt;region-attributes&gt;
&lt;/region-attributes&gt;
&lt;/region&gt;
&lt;/shared-root-region&gt;
...
</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
@ -965,8 +664,8 @@ mechanism, extend <classname>org.apache.openjpa.datacache.AbstractDataCache
</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"/>
.
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
@ -985,7 +684,7 @@ directly.
<listitem>
<para>
The default cache implementations <emphasis>do not</emphasis> automatically
refresh objects in other <classname> EntityManager</classname>s when the cache
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>
@ -995,7 +694,7 @@ specification.
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
<xref linkend="ref_guide_cache_pmevict"/>). Other methods related to the
<classname>EntityManager</classname> cache also do not effect the data cache.
</para>
<para>
@ -1073,146 +772,20 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
Extent extent = kem.getExtent (Magazine.class, false);
OpenJPAEntityManager oem = OpenJPAPersistence.cast(em);
Extent extent = oem.getExtent(Magazine.class, false);
// This iterator does not benefit from caching...
Iterator uncachedIterator = extent.iterator ();
Iterator uncachedIterator = extent.iterator();
// ... but this one does.
OpenJPAQuery extentQuery = kem.createQuery (...);
extentQuery.setSubclasses (false);
Iterator cachedIterator = extentQuery.getResultList ().iterator ();
OpenJPAQuery extentQuery = oem.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>

View File

@ -94,141 +94,103 @@ entity managers into your session beans using the <literal>PersistenceContext
</indexterm>
<para>
OpenJPA <classname>EntityManager</classname>s have the ability to automatically
synchronize their transactions with an external transaction manager.
###
If you
deploy via <link linkend="ref_guide_deploy_inject"><classname>EntityManager
</classname> injection</link> as described above, this synchronization is
typically automatic. Whether
synchronize their transactions with an external transaction manager. Whether
or not <classname>EntityManager</classname>s from a given <classname>
EntityManagerFactory</classname> exhibit this behavior by default depends on
the <link linkend="kodo.TransactionMode">
<literal>kodo.TransactionMode</literal></link> configuration property.
The property can take the following values:
</para>
<para condition="jdo_notcombo">
Kodo <classname>PersistenceManager</classname>s have the ability
to automatically synchronize their transactions with an external
transaction manager. Whether or not <classname>
PersistenceManager</classname>s from a given
<classname>PersistenceManagerFactory</classname> exhibit this behavior
by default depends on the <link linkend="kodo.TransactionMode">
<literal>kodo.TransactionMode</literal></link> configuration property.
The property can take the following values:
</para>
<para condition="combo">
Kodo <classname>EntityManager</classname>s and <classname>
PersistenceManager</classname>s have the ability
to automatically synchronize their transactions with an external
transaction manager. Whether or not <classname>
EntityManager</classname>s and <classname>
PersistenceManager</classname>s from a given factory exhibit this
behavior by default depends on the <link linkend="kodo.TransactionMode">
<literal>kodo.TransactionMode</literal></link> configuration property.
The property can take the following values:
</para>
the transaction type you set for the factory's persistence unit in
your <filename>persistence.xml</filename> file. OpenJPA uses the given
transaction type internally to set the
<link linkend="openjpa.TransactionMode"><literal>openjpa.TransactionMode
</literal></link> configuration property. This property accepts the following
modes:
</para>
<itemizedlist>
<listitem>
<para>
<literal>local</literal>: Perform transaction operations
locally.
<literal>local</literal>: Perform transaction operations locally.
</para>
</listitem>
<listitem>
<para>
<literal>managed</literal>: Integrate with the application
server's managed global transactions.
<literal>managed</literal>: Integrate with the application server's managed
global transactions.
</para>
</listitem>
</itemizedlist>
<para condition="ejb">
You can override the global transaction mode setting when you obtain an
<classname>EntityManager</classname> using the
<ulink url="&api-dir;/kodo/persistence/KodoEntityManagerFactory.html">
<classname>KodoEntityManagerFactory</classname></ulink>'s
<methodname>createEntityManager(PersistenceContextType ctype, boolean managed, int connRetainMode)
</methodname> method.
</para>
<para condition="jdo">
You can override the global transaction mode setting when you obtain a
<classname>PersistenceManager</classname> using the
<ulink url="&api-dir;/kodo/jdo/KodoPersistenceManagerFactory.html">
<classname>KodoPersistenceManagerFactory</classname></ulink>'s
<methodname>getPersistenceManager(boolean managed, int connRetainMode)
</methodname> method.
<para>
You can override the global transaction mode setting when you obtain an
<classname>EntityManager</classname> using the
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/EntityManagerFactory.html">
<classname>EntityManagerFactory</classname></ulink>'s
<methodname>createEntityManager(Map props)</methodname> method. Simply set the
<literal>openjpa.TransactionMode</literal> key of the given <classname>Map
</classname> to the desired value.
</para>
<note>
<para>
You can also override the <literal>openjpa.ConnectionUserName</literal>,
<literal>openjpa.ConnectionPassword</literal>, and <literal>
openjpa.ConnectionRetainMode</literal> settings using the given <classname>
Map</classname>.
</para>
</note>
<para>
<indexterm><primary>ManagedRuntime</primary></indexterm>
In order to use global transactions, Kodo must be able to access
the application server's <classname>javax.transaction.TransactionManager
</classname>. Kodo can automatically discover the transaction
manager for most major application servers. Occasionally, however,
you might have to point Kodo to the transaction manager for an
unrecognized or non-standard application server setup. This is
accomplished through the <link linkend="kodo.ManagedRuntime"><literal>
kodo.ManagedRuntime</literal></link> configuration property. This
property describes a
<ulink url="&javadoc-dir;/kodo/ee/ManagedRuntime.html"><classname>
kodo.ee.ManagedRuntime</classname></ulink> implementation to use
for transaction manager discovery. You can specify your own
implementation, or use one of the built-ins:
<indexterm><primary>ManagedRuntime</primary></indexterm>
In order to use global transactions, OpenJPA must be able to access the
application server's <classname>
javax.transaction.TransactionManager</classname>. OpenJPA can automatically
discover the transaction manager for most major application servers.
Occasionally, however, you might have to point OpenJPA to the transaction
manager for an unrecognized or non-standard application server setup. This is
accomplished through the <link linkend="openjpa.ManagedRuntime"><literal>
openjpa.ManagedRuntime</literal></link> configuration property. This
property describes an
<ulink url="../apidocs/org/apache/openjpa/ee/ManagedRuntime.html"><classname>
org.apache.openjpa.ee.ManagedRuntime</classname></ulink> implementation to use
for transaction manager discovery. You can specify your own implementation,
or use one of the built-ins:
</para>
<itemizedlist>
<listitem>
<para>
<literal>auto</literal>: This is the default. It is an alias
for the
<ulink url="&javadoc-dir;/kodo/ee/AutomaticManagedRuntime.html">
<classname>kodo.ee.AutomaticManagedRuntime</classname></ulink>
class. This managed runtime is able to automatically integrate
with several common application servers.
<literal>auto</literal>: This is the default. It is an alias for the
<ulink url="../apidocs/org/apache/openjpa/ee/AutomaticManagedRuntime.html">
<classname>org.apache.openjpa.ee.AutomaticManagedRuntime</classname></ulink>
class. This managed runtime is able to automatically integrate with several
common application servers.
</para>
</listitem>
<listitem>
<para>
<literal>invocation</literal>: An alias for the
<ulink url="&javadoc-dir;/kodo/ee/InvocationManagedRuntime.html">
<classname>kodo.ee.InvocationManagedRuntime</classname></ulink>
class. You can configure this runtime to invoke any static
method in order to obtain the appserver's transaction manager.
<literal>invocation</literal>: An alias for the
<ulink url="../apidocs/org/apache/openjpa/ee/InvocationManagedRuntime.html">
<classname>org.apache.openjpa.ee.InvocationManagedRuntime</classname></ulink>
class. You can configure this runtime to invoke any static
method in order to obtain the appserver's transaction manager.
</para>
</listitem>
<listitem>
<para>
<literal>jndi</literal>: An alias for the
<ulink url="&javadoc-dir;/kodo/ee/JNDIManagedRuntime.html">
<classname>kodo.ee.JNDIManagedRuntime</classname></ulink>
class. You can configure this runtime to look up the
transaction manager at any JNDI location.
<literal>jndi</literal>: An alias for the
<ulink url="../apidocs/org/apache/openjpa/ee/JNDIManagedRuntime.html">
<classname>org.apache.openjpa.ee.JNDIManagedRuntime</classname></ulink>
class. You can configure this runtime to look up the transaction manager at
any JNDI location.
</para>
</listitem>
</itemizedlist>
<para>
See the Javadoc for of each class for details on the bean properties
you can pass to these plugins in your configuration string.
See the Javadoc for of each class for details on the bean properties
you can pass to these plugins in your configuration string.
</para>
&feature-enterprise;
<example id="ref_guide_enterprise_transex">
<title>Configuring Transaction Manager Integration</title>
<para condition="combo">JPA XML format:</para>
<programlisting condition="ejb">
<![CDATA[<property name="kodo.TransactionMode" value="managed"/>
<property name="kodo.ManagedRuntime" value="jndi(TransactionManagerName=java:/TransactionManager)"/>]]>
</programlisting>
<para condition="combo">JDO properties format:</para>
<programlisting condition="jdo">
kodo.TransactionMode: managed
kodo.ManagedRuntime: jndi(TransactionManagerName=java:/TransactionManager)
<programlisting>
<![CDATA[<property name="openjpa.TransactionMode" value="managed"/>
<property name="openjpa.ManagedRuntime" value="jndi(TransactionManagerName=java:/TransactionManager)"/>]]>
</programlisting>
</example>
<para>
Note that even when Kodo is using managed transaction, you can control
transactions through the specification local transaction APIs if you
wish. Kodo will propagate your transaction calls to the global
transaction.
</para>
</section>
<section id="ref_guide_enterprise_xa">
<title>
XA Transactions
@ -315,6 +277,12 @@ Given these components, setting up OpenJPA to participate in distributed
transactions is a simple two-step process:
</para>
<orderedlist>
<listitem>
<para>
Integrate OpenJPA with your application server's transaction manager, as
detailed in <xref linkend="ref_guide_enterprise_trans"/> above.
</para>
</listitem>
<listitem>
<para>
Point OpenJPA at an enlisted <classname>XADataSource</classname>, and configure

View File

@ -112,29 +112,27 @@ loaded relative to the current CLASSPATH.
</para>
<example id="ref_guide_integration_props">
<title>
Using the Properties Attribute of the &lt;config&gt;
Tag
Using the Properties Attribute of the &lt;config&gt; Tag
</title>
<programlisting>
&lt;mappingtool&gt;
&lt;fileset dir="${basedir}"&gt;
&lt;include name="**/model/*.java"/&gt;
&lt;/fileset&gt;
&lt;config properties="openjpa-dev.properties"/&gt;
&lt;config properties="openjpa-dev.xml"/&gt;
&lt;/mappingtool&gt;
</programlisting>
</example>
<example id="ref_guide_integration_propsfile">
<title>
Using the PropertiesFile Attribute of the &lt;config&gt;
Tag
Using the PropertiesFile Attribute of the &lt;config&gt; Tag
</title>
<programlisting>
&lt;mappingtool&gt;
&lt;fileset dir="${basedir}"&gt;
&lt;include name="**/model/*.java"/&gt;
&lt;/fileset&gt;
&lt;config propertiesFile="../conf/openjpa-dev.properties"/&gt;
&lt;config propertiesFile="../conf/openjpa-dev.xml"/&gt;
&lt;/mappingtool&gt;
</programlisting>
</example>
@ -209,15 +207,17 @@ formatting attributes.
<para>
The enhancer task allows you to invoke the OpenJPA enhancer directly from within
the Ant build process. The task's parameters correspond exactly to the long
versions of the command-line arguments to <link linkend="ref_guide_pc_enhance">
<literal>openjpac</literal></link>.
versions of the command-line arguments to the
<link linkend="ref_guide_pc_enhance"><classname>
org.apache.openjpa.enhance.PCEnhancer</classname></link>.
</para>
<para>
The enhancer task accepts a nested <literal>fileset</literal> tag to specify the
files that should be processed. You can specify <filename>.java</filename> or
<filename>.class</filename> files. If you do not specify any files, the task
will run on the classes listed in your <link linkend="openjpa.MetaDataFactory">
<literal> openjpa.MetaDataFactory</literal></link> property.
will run on the classes listed in your <filename>persistence.xml</filename> or
<link linkend="openjpa.MetaDataFactory"><literal>
openjpa.MetaDataFactory</literal></link> property.
</para>
<para>
Following is an example of using the enhancer task in a <filename>build.xml
@ -266,17 +266,17 @@ Following is an example of using the enhancer task in a <filename>build.xml
<para>
The application identity tool task allows you to invoke the application identity
tool directly from within the Ant build process. The task's parameters
correspond exactly to the long versions of the command-line arguments to
<link linkend="ref_guide_pc_appid_appidtool"><literal>appidtool</literal></link>
.
correspond exactly to the long versions of the command-line arguments to the
<link linkend="ref_guide_pc_appid_appidtool"><classname>
org.openjpa.enhance.ApplicationIdTool</classname></link>.
</para>
<para>
The application identity tool task accepts a nested <literal>fileset</literal>
tag to specify the files that should be processed. You can specify <filename>
.java</filename> or <filename>.class</filename> files. If you do not specify any
files, the task will run on the classes listed in your
<link linkend="openjpa.MetaDataFactory"><literal> openjpa.MetaDataFactory
</literal></link> property.
files, the task will run on the classes listed in your <filename>persistence.xml
</filename> file or <link linkend="openjpa.MetaDataFactory"><literal>
openjpa.MetaDataFactory</literal></link> property.
</para>
<para>
Following is an example of using the application identity tool task in a
@ -330,14 +330,15 @@ object-relational mapping data is always synchronized with your persistent class
definitions, without needing to remember to invoke the mapping tool manually.
The task's parameters correspond exactly to the long versions of the
command-line arguments to the <link linkend="ref_guide_mapping_mappingtool">
<literal>mappingtool</literal></link>.
<classname>org.apache.openjpa.jdbc.meta.MappingTool</classname></link>.
</para>
<para>
The mapping tool task accepts a nested <literal>fileset</literal> tag to specify
the files that should be processed. You can specify <filename>.java</filename>
or <filename>.class</filename> files. If you do not specify any files, the task
will run on the classes listed in your <link linkend="openjpa.MetaDataFactory">
<literal> openjpa.MetaDataFactory</literal></link> property.
will run on the classes listed in your <filename>persistence.xml</filename> file
or <link linkend="openjpa.MetaDataFactory"><literal>
openjpa.MetaDataFactory</literal></link> property.
</para>
<para>
Following is an example of a <filename>build.xml</filename> target that invokes
@ -389,8 +390,8 @@ The reverse mapping tool task allows you to directly invoke the reverse mapping
tool from within Ant. While many users will only run the reverse mapping process
once, others will make it part of their build process. The task's parameters
correspond exactly to the long versions of the command-line arguments to the
<link linkend="ref_guide_pc_reverse_reversemappingtool"><literal>
reversemappingtool</literal></link>.
<link linkend="ref_guide_pc_reverse_reversemappingtool"><classname>
org.apache.openjpa.jdbc.meta.ReverseMappingTool</classname></link>.
</para>
<para>
Following is an example of a <filename>build.xml</filename> target that invokes
@ -440,8 +441,8 @@ the reverse mapping tool:
The schema tool task allows you to directly invoke the schema tool from within
the Ant build process. The task's parameters correspond exactly to the long
versions of the command-line arguments to the
<link linkend="ref_guide_schema_schematool"><literal> schematool</literal>
</link>.
<link linkend="ref_guide_schema_schematool"><classname>
org.apache.openjpa.jdbc.schema.SchemaTool</classname></link>.
</para>
<para>
Following is an example of a <filename>build.xml</filename> target that invokes
@ -469,14 +470,4 @@ the schema tool:
</example>
</section>
</section>
<section id="ref_guide_integration_maven">
<title>
Maven
</title>
<indexterm zone="ref_guide_integration_maven">
<primary>
Maven
</primary>
</indexterm>
</section>
</chapter>

View File

@ -37,10 +37,23 @@ more work onto the server will have a negative impact on scalability.
</title>
<tgroup cols="2" align="left" colsep="1" rowsep="1">
<colspec colname="name"/>
<colspec colname="desc" colwidth="4*"/>
<tbody valign="top">
<row>
<entry colname="name">
<emphasis role="bold">
Plugin in a Connection Pool
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
OpenJPA's built-in datasource does not perform connection pooling or
prepared statement caching. Plugging in a third-party pooling datasource may
drastically improve performance.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
@ -51,15 +64,11 @@ more work onto the server will have a negative impact on scalability.
</para>
</entry>
<entry colname="desc">
The default set of indexes created by OpenJPA's mapping
tool may not always be the most appropriate for your
application. Manually setting indexes in your mapping
metadata or manually manipulating database indexes to
include frequently-queried fields (as well as dropping
indexes on rarely-queried fields) can yield significant
performance benefits.
The default set of indexes created by OpenJPA's mapping tool may not always be
the most appropriate for your application. Manually setting indexes in your
mapping metadata or manually manipulating database indexes to include
frequently-queried fields (as well as dropping indexes on rarely-queried
fields) can yield significant performance benefits.
<para>
A database must do extra work on insert, update, and delete to maintain an
index. This extra work will benefit selects with WHERE clauses, which will
@ -76,26 +85,6 @@ or deletes.
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Use the best JDBC driver
</emphasis>
<para>
<emphasis>performance, scalability, reliability</emphasis>
</para>
</entry>
<entry colname="desc">
The JDBC driver provided by the database vendor is not
always the fastest and most efficient. Some JDBC drivers
do not support features like batched statements, the lack
of which can significantly slow down OpenJPA's data access
and increase load on the database, reducing system
performance and scalability.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
@ -106,16 +95,10 @@ or deletes.
</para>
</entry>
<entry colname="desc">
Manipulating various parameters of the Java Virtual Machine
(such as hotspot compilation modes and the maximum memory)
can result in performance improvements. For more details
about optimizing the JVM execution environment, please see
<ulink url="http://java.sun.com/docs/hotspot/PerformanceFAQ.html">
</ulink>
.
Manipulating various parameters of the Java Virtual Machine (such as hotspot
compilation modes and the maximum memory) can result in performance
improvements. For more details about optimizing the JVM execution environment,
please see <ulink url="http://java.sun.com/docs/hotspot/PerformanceFAQ.html"/>.
</entry>
</row>
<row>
@ -128,74 +111,32 @@ or deletes.
</para>
</entry>
<entry colname="desc">
Using OpenJPA's
<link linkend="ref_guide_cache">
data and
query caching
</link>
features can often result
in a dramatic improvement in performance. Additionally,
these caches can significantly reduce the amount of load on
the database, increasing the scalability characteristics of
your application. Also, be sure to read about the
<link linkend="ref_guide_cache_concurrent">
concurrent cache
</link>
option to see if it fits your needs.
Using OpenJPA's <link linkend="ref_guide_cache">data and query caching</link>
features can often result in a dramatic improvement in performance.
Additionally, these caches can significantly reduce the amount of load on
the database, increasing the scalability characteristics of your application.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Set
<literal>
LargeTransaction
</literal>
to true, or set
<literal>
PopulateDataCache
</literal>
to false
Set <literal>LargeTransaction</literal> to true,
or set <literal> PopulateDataCache</literal> to
false
</emphasis>
<para>
<emphasis>performance vs. scalability</emphasis>
</para>
</entry>
<entry colname="desc">
When using OpenJPA's
<link linkend="ref_guide_cache">
data
caching
</link>
features (available in OpenJPA JDO
Performance Pack and Enterprise Edition)
in a transaction that will delete, modify, or create
a very large number of objects you can set
<literal>
LargeTransaction
</literal>
to true and perform periodic
flushes during your transaction to reduce its memory
requirements. See the Javadoc:
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
OpenJPAEntityManager.setLargeTransaction
</ulink>
Note that transactions in large mode have to
more aggressively flush items from the data cache.
When using OpenJPA's <link linkend="ref_guide_cache">data caching</link>
features in a transaction that will delete, modify, or create a very large
number of objects you can set <literal>LargeTransaction</literal> to true and
perform periodic flushes during your transaction to reduce its memory
requirements. See the Javadoc:
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html">
OpenJPAEntityManager.setLargeTransaction</ulink>. Note that transactions in
large mode have to more aggressively flush items from the data cache.
<para>
If your transaction will visit objects that you know are very unlikely to be
accessed by other transactions, for example an exhaustive report run only once a
@ -210,94 +151,42 @@ OpenJPAEntityManager.setPopulateDataCache</ulink>
<row>
<entry colname="name">
<emphasis role="bold">
Disable logging, performance
tracking
Disable logging, performance tracking
</emphasis>
<para>
<emphasis>performance</emphasis>
</para>
</entry>
<entry colname="desc">
Developer options such as verbose logging and the
JDBC performance tracker can result in serious performance
hits for your application. Before evaluating OpenJPA's
performance, these options should all be disabled.
Developer options such as verbose logging and the JDBC performance tracker can
result in serious performance hits for your application. Before evaluating
OpenJPA's performance, these options should all be disabled.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Set
<literal>
IgnoreChanges
</literal>
to true, or set
<literal>
FlushBeforeQueries
</literal>
to
true
Set <literal>IgnoreChanges</literal> to true, or
set <literal>FlushBeforeQueries</literal> to true
</emphasis>
<para>
<emphasis>performance vs. scalability</emphasis>
</para>
</entry>
<entry colname="desc">
When both the
<link linkend="openjpa.IgnoreChanges">
<literal>
openjpa.IgnoreChanges
</literal>
</link>
and
<link linkend="openjpa.FlushBeforeQueries">
<literal>
openjpa.FlushBeforeQueries
</literal>
</link>
properties are set
to false, OpenJPA needs to consider in-memory dirty instances
during queries. This can sometimes result in OpenJPA needing
to evaluate the entire extent objects in order to
return the correct query results, which can have drastic
performance consequences. If it is appropriate for your
application, configuring
<literal>
FlushBeforeQueries
</literal>
to automatically flush before queries involving dirty
objects will ensure that this never
happens. Setting
<literal>
IgnoreChanges
</literal>
to
false will result in a small performance hit even if
<literal>
FlushBeforeQueries
</literal>
is true, as
incremental flushing is not as efficient overall as
delaying all flushing to a single operation during commit.
This is because incrementally flushing decreases OpenJPA's
ability to maximize statement batching, and increases
resource utilization.
<para>
Note that the default setting of <literal>FlushBeforeQueries</literal> is
<literal>with-connection</literal>, which means that data will be flushed only
if a dedicated connection is already in use by the <classname>EntityManager
</classname>. So, the default value may not be appropriate for you.
</para>
When both the <link linkend="openjpa.IgnoreChanges"><literal>
openjpa.IgnoreChanges</literal></link> and
<link linkend="openjpa.FlushBeforeQueries"><literal>openjpa.FlushBeforeQueries
</literal></link> properties are set to false, OpenJPA needs to consider
in-memory dirty instances during queries. This can sometimes result in OpenJPA
needing to evaluate the entire extent objects in order to return the correct
query results, which can have drastic performance consequences. If it is
appropriate for your application, configuring <literal>FlushBeforeQueries
</literal> to automatically flush before queries involving dirty objects will
ensure that this never happens. Setting <literal>IgnoreChanges</literal> to
false will result in a small performance hit even if <literal>FlushBeforeQueries
</literal> is true, as incremental flushing is not as efficient overall as
delaying all flushing to a single operation during commit.
<para>
Setting <literal>IgnoreChanges</literal> to <literal>true</literal> will help
performance, since dirty objects can be ignored for queries, meaning that
@ -312,41 +201,26 @@ before queries, since more operations will be performed on the database server.
<row>
<entry colname="name">
<emphasis role="bold">
Configure
<literal>
openjpa.ConnectionRetainMode
</literal>
appropriately
Configure <literal>openjpa.ConnectionRetainMode
</literal> appropriately
</emphasis>
<para>
<emphasis>performance vs. scalability</emphasis>
</para>
</entry>
<entry colname="desc">
The
<link linkend="openjpa.ConnectionRetainMode">
<literal>
ConnectionRetainMode
</literal>
</link>
configuration option
controls when OpenJPA will obtain a connection, and how long
it will hold that connection. The optimal settings for this
option will vary considerably depending on the particular
behavior of your application. You may even benefit from
using different retain modes for different parts of your
application.
The <link linkend="openjpa.ConnectionRetainMode"><literal>ConnectionRetainMode
</literal></link> configuration option controls when OpenJPA will obtain a
connection, and how long it will hold that connection. The optimal settings for
this option will vary considerably depending on the particular behavior of
your application. You may even benefit from using different retain modes for
different parts of your application.
<para>
The default setting of <literal>on-demand</literal> minimizes the amount of time
that OpenJPA holds onto a datastore connection. This is generally the best
option from a scalability standpoind, as database resources are held for a
minimal amount of time. However, if your connection pool is overly small
relative to the number of concurrent sessions that need access to the database,
or if your <classname>DataSource</classname> is not efficient at managing its
minimal amount of time. However, if you are not using connection pooling, or
if your <classname>DataSource</classname> is not efficient at managing its
pool, then this default value could cause undesirable pool contention.
</para>
</entry>
@ -354,40 +228,17 @@ pool, then this default value could cause undesirable pool contention.
<row>
<entry colname="name">
<emphasis role="bold">
Ensure that batch updates are
available
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
When performing bulk inserts, updates, or deletes, OpenJPA
will use batched statements. If this feature is not
available in your JDBC driver, then OpenJPA will need to
issue multiple SQL statements instead of a single batch
statement.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Use
flat inheritance
Use flat inheritance
</emphasis>
<para>
<emphasis>performance, scalability vs. disk space</emphasis>
</para>
</entry>
<entry colname="desc">
Mapping inheritance hierarchies to a single database table
is faster for most operations than other strategies
employing multiple tables. If it is appropriate for your
application, you should use this strategy whenever possible.
Mapping inheritance hierarchies to a single database table is faster for most
operations than other strategies employing multiple tables. If it is
appropriate for your application, you should use this strategy whenever
possible.
<para>
However, this strategy will require more disk space on the database side. Disk
space is relatively inexpensive, but if your object model is particularly large,
@ -405,15 +256,11 @@ it can become a factor.
</para>
</entry>
<entry colname="desc">
For applications that perform large bulk inserts, the
retrieval of sequence numbers can be a bottleneck.
Increasing sequence increments and using table-based rather
than native database sequences can reduce or eliminate
this bottleneck. In some cases,
implementing your own sequence factory can further optimize
sequence number retrieval.
For applications that perform large bulk inserts, the retrieval of sequence
numbers can be a bottleneck. Increasing sequence increments and using
table-based rather than native database sequences can reduce or eliminate
this bottleneck. In some cases, implementing your own sequence factory can
further optimize sequence number retrieval.
</entry>
</row>
<row>
@ -426,13 +273,10 @@ it can become a factor.
</para>
</entry>
<entry colname="desc">
Using datastore transactions translates into pessimistic
database row locking, which can be a performance hit
(depending on the database). If appropriate for your
application, optimistic transactions are typically faster
than datastore transactions.
Using datastore transactions translates into pessimistic database row locking,
which can be a performance hit (depending on the database). If appropriate for
your application, optimistic transactions are typically faster than datastore
transactions.
<para>
Optimistic transactions provide the same transactional guarantees as datastore
transactions, except that you must handle a potential optimistic verification
@ -451,21 +295,17 @@ the user redo any work.
<entry colname="name">
<emphasis role="bold">
Use query aggregates and projections
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
Using aggregates to compute reporting data on the database
server can drastically speed up queries. Similarly, using
projections when you are interested in specific
object fields or relations rather than the entire object
state can reduce the amount of data OpenJPA must transfer
from the database to your application.
Using aggregates to compute reporting data on the database server can
drastically speed up queries. Similarly, using projections when you are
interested in specific object fields or relations rather than the entire object
state can reduce the amount of data OpenJPA must transfer from the database to
your application.
</entry>
</row>
<row>
@ -493,30 +333,6 @@ close them, but it is always faster if it is done at the application level.
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Optimize connection pool
settings
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
<para>
OpenJPA's built-in connection pool's default settings may not be optimal for all
applications. For applications that instantiate and close many <classname>
EntityManager</classname>s (such as a web application), increasing the size of
the connection pool will reduce the overhead of waiting on free connections or
opening new connections.
</para>
<para>
You may want to tune the prepared statement pool size with the connection pool
size.
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
@ -545,205 +361,91 @@ client tier.
<row>
<entry colname="name">
<emphasis role="bold">
Utilize the
<classname>
EntityManager
</classname>
cache
Utilize the <classname>EntityManager</classname>
cache
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
When possible and appropriate, re-using
<classname>
EntityManager
</classname>
s and setting the
<link linkend="openjpa.RetainState">
<literal>
RetainState
</literal>
</link>
configuration option to
<literal>
true
</literal>
may result in significant
performance gains, since the
<classname>
EntityManager
</classname>
's built-in
object cache will be used.
When possible and appropriate, re-using <classname>EntityManager</classname>s
and setting the <link linkend="openjpa.RetainState"><literal>RetainState
</literal></link> configuration option to <literal>true</literal> may result in
significant performance gains, since the <classname>EntityManager</classname>'s
built-in object cache will be used.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Enable multithreaded operation only
when necessary
Enable multithreaded operation only when necessary
</emphasis>
<para>
<emphasis>performance</emphasis>
</para>
</entry>
<entry colname="desc">
OpenJPA respects the
<link linkend="openjpa.Multithreaded">
<literal>
openjpa.Multithreaded
</literal>
</link>
option in
that it does not impose synchronization overhead for
applications that set this value to
<literal>
false
</literal>
. If your application is
guaranteed to only use single-threaded access to OpenJPA
resources and persistent objects, setting this option to
<literal>
false
</literal>
will result
in the elimination of synchronization overhead, and may
result in a modest performance increase.
OpenJPA respects the <link linkend="openjpa.Multithreaded"><literal>
openjpa.Multithreaded</literal></link> option in that it does not impose as
much synchronization overhead for applications that do not set this value to
<literal>true</literal>. If your application is guaranteed to only use
single-threaded access to OpenJPA resources and persistent objects, leaving
this option as <literal>false</literal> will reduce synchronization overhead,
and may result in a modest performance increase.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Enable large data set
handling
Enable large data set handling
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
If you execute queries that return large numbers of objects
or have relations (collections or maps) that are large, and
if you often only access parts of these data sets, enabling
<link linkend="ref_guide_dbsetup_lrs">
large result set
handling
</link>
where appropriate can
dramatically speed up your application, since OpenJPA will
bring the data sets into memory from the database only as
necessary.
If you execute queries that return large numbers of objects or have relations
(collections or maps) that are large, and if you often only access parts of
these data sets, enabling <link linkend="ref_guide_dbsetup_lrs">large result
set handling</link> where appropriate can dramatically speed up your
application, since OpenJPA will bring the data sets into memory from the
database only as necessary.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Disable large data set handling
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
If you have enabled scrollable result sets and on-demand
loading but do you not require it, consider disabling it
again. Some JDBC drivers and databases (SQLServer for
example) are much slower when used with scrolling result
sets.
If you have enabled scrollable result sets and on-demand loading but do you not
require it, consider disabling it again. Some JDBC drivers and databases
(SQLServer for example) are much slower when used with scrolling result sets.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Use short discriminator values, or
turn off the discriminator
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
The default discriminator strategy of storing the class
name in the discriminator column is quite robust, in that
it can handle any class and needs no configuration, but
the downside of this robustness is that it puts a
relatively lengthy string into each row of the database.
With a little application-specific configuration, you can
easily reduce this to a single character or integer. This
can result in significant performance gains when dealing
with many small objects,
since the subclass indicator data can become a significant
proportion of the data transferred between the JVM and
the database.
<para>
Alternately, if certain persistent classes in your application do not make use
of inheritance, then you can disable the discriminator for these classes
altogether.
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Use the
<classname>
DynamicSchemaFactory
</classname>
Use the <classname>DynamicSchemaFactory</classname>
</emphasis>
<para>
<emphasis>performance, validation</emphasis>
</para>
</entry>
<entry colname="desc">
If you are using a
<link linkend="openjpa.jdbc.SchemaFactory">
<literal>
openjpa.jdbc.SchemaFactory
</literal>
</link>
setting
of something other than the default of
<literal>
dynamic
</literal>
, consider switching back. While other
factories can ensure that object-relational mapping
information is valid when a persistent class is first used,
this can be a slow process. Though the validation is only
performed once for each class, switching back to the
<classname>
DynamicSchemaFactory
</classname>
can reduce the warm-up time for your application.
If you are using a <link linkend="openjpa.jdbc.SchemaFactory"><literal>
openjpa.jdbc.SchemaFactory</literal></link> setting of something other than
the default of <literal>dynamic</literal>, consider switching back. While other
factories can ensure that object-relational mapping information is valid when
a persistent class is first used, this can be a slow process. Though the
validation is only performed once for each class, switching back to the
<classname>DynamicSchemaFactory</classname> can reduce the warm-up time for
your application.
</entry>
</row>
<row>
@ -756,14 +458,9 @@ altogether.
</para>
</entry>
<entry colname="desc">
<link linkend="ref_guide_enterprise_xa">
XA transactions
</link>
can be orders of magnitude slower than standard
transactions. Unless distributed transaction functionality
is required by your application, use standard transactions.
<link linkend="ref_guide_enterprise_xa">XA transactions</link> can be orders of
magnitude slower than standard transactions. Unless distributed transaction
functionality is required by your application, use standard transactions.
<para>
Recall that XA transactions are distinct from managed transactions - managed
transaction services such as that provided by EJB declarative transactions can
@ -777,88 +474,37 @@ example).
<row>
<entry colname="name">
<emphasis role="bold">
Use
<classname>
Set
</classname>
s
instead of
<classname>
List/Collection
</classname>
s
Use <classname>Set</classname>s instead of
<classname>List/Collection</classname>s
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
There is a small amount of extra overhead for OpenJPA to
maintain collections where each element is not guaranteed
to be unique. If your application does not require
duplicates for a collection, you should always declare your
fields to be of type
<classname>
Set, SortedSet,
HashSet,
</classname>
or
<classname>
TreeSet
</classname>
.
There is a small amount of extra overhead for OpenJPA to maintain collections
where each element is not guaranteed to be unique. If your application does
not require duplicates for a collection, you should always declare your
fields to be of type <classname>Set, SortedSet, HashSet,</classname> or
<classname>TreeSet</classname>.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Use query parameters instead of
encoding search data in filter strings
</emphasis>
<para>
<emphasis>performance</emphasis>
</para>
</entry>
<entry colname="desc">
If your queries depend on parameter data only known at
runtime, you should use query parameters rather than
dynamically building different query strings. OpenJPA
performs aggressive caching of query compilation
data, and the effectiveness of this cache is diminished if
multiple query filters are used where a single one could
have sufficed.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">
Tune your fetch groups
appropriately
Tune your fetch groups appropriately
</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</para>
</entry>
<entry colname="desc">
The
<link linkend="ref_guide_fetch">
fetch groups
</link>
used when loading an object control how much data is
eagerly loaded, and by extension, which fields must be
lazily loaded at a future time. The ideal fetch group
configuration loads all the data that is needed in one
fetch, and no extra fields - this minimizes both the
amount of data transferred from the database, and the
number of trips to the database.
The <link linkend="ref_guide_fetch">fetch groups</link> used when loading an
object control how much data is eagerly loaded, and by extension, which fields
must be lazily loaded at a future time. The ideal fetch group configuration
loads all the data that is needed in one fetch, and no extra fields - this
minimizes both the amount of data transferred from the database, and the
number of trips to the database.
<para>
If extra fields are specified in the fetch groups (in particular, large fields
such as binary data, or relations to other persistence-capable objects), then
@ -879,16 +525,9 @@ trips to the database to load additional fields as necessary.
</para>
</entry>
<entry colname="desc">
Using
<link linkend="ref_guide_perfpack_eager">
eager
fetching
</link>
when loading subclass data or traversing
relations for each instance in a large collection of
results can speed up data loading by orders of magnitude.
Using <link linkend="ref_guide_perfpack_eager">eager fetching</link> when
loading subclass data or traversing relations for each instance in a large
collection of results can speed up data loading by orders of magnitude.
</entry>
</row>
</tbody>

View File

@ -22,9 +22,9 @@ such as <classname>EntityManager</classname>s and queries connect directly to
the datastore and execute their actions in the same JVM as the code using them.
It is <emphasis>online</emphasis> in that all changes to managed objects must be
made in the context of an active <classname> EntityManager</classname>. These
two properties, combined with the fact that <classname> EntityManager
</classname>s cannot be serialized for storage or network transfer, make the
standard JPA runtime difficult to incorporate into some enterprise and
two properties, combined with the fact that <classname>
EntityManager</classname>s cannot be serialized for storage or network transfer,
make the standard JPA runtime difficult to incorporate into some enterprise and
client/server program designs.
</para>
<para>
@ -78,9 +78,9 @@ The extended
explicitly detach objects at any time.
</para>
<programlisting>
public Object detach (Object pc):
public Object[] detachAll (Object... pcs):
public Collection detachAll (Collection pcs):
public Object detach(Object pc):
public Object[] detachAll(Object... pcs):
public Collection detachAll(Collection pcs):
</programlisting>
<para>
Each detach method returns detached copies of the given instances. The copy
@ -220,11 +220,9 @@ default.
</listitem>
<listitem>
<para>
<literal>fgs</literal>: Detach all fields and relations in the default fetch
group, and any other fetch groups that you have added to the current
<literal>fgs</literal>: Detach all fields and relations in the current
<link linkend="ref_guide_runtime">fetch configuration</link>. For more
information on custom fetch groups, see <xref linkend="ref_guide_fetch"/>
.
information on custom fetch groups, see <xref linkend="ref_guide_fetch"/>.
</para>
</listitem>
<listitem>
@ -330,8 +328,8 @@ for controlling detached state:
public static final int DETACH_LOADED;
public static final int DETACH_FGS;
public static final int DETACH_ALL;
public int getDetachState ();
public void setDetachState (int mode);
public int getDetachState();
public void setDetachState(int mode);
</programlisting>
<section id="ref_guide_detach_field">
<title>
@ -365,8 +363,8 @@ import org.apache.openjpa.persistence.*;
@Entity
public class Magazine
implements Serializable
{
implements Serializable {
private String name;
@DetachedState private Object state;
...
@ -474,7 +472,6 @@ OpenJPA includes built in remote commit providers for JMS and TCP communication.
</tertiary>
</indexterm>
<para>
OpenJPA includes built in remote commit providers for JMS and TCP communication.
The JMS remote commit provider can be configured by setting the
<link linkend="openjpa.RemoteCommitProvider"><literal>
openjpa.RemoteCommitProvider</literal></link> property to contain the
@ -551,7 +548,7 @@ The TCP remote commit provider has several options that are defined as host
specifications containing a host name or IP address and an optional port
separated by a colon. For example, the host specification <literal>
saturn.bea.com:1234</literal> represents an <classname>InetAddress</classname>
retrieved by invoking <methodname>InetAddress.getByName ("saturn.bea.com")
retrieved by invoking <methodname>InetAddress.getByName("saturn.bea.com")
</methodname> and a port of 1234.
</para>
<para>

View File

@ -85,7 +85,7 @@ 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.
and <classname>Broker</classname>s.
</para>
<section id="ref_guide_runtime_pmextension">
<title>
@ -153,14 +153,14 @@ 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);
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>.
</classname> helper <link linkend="ref_guide_runtime_openjpapersistence">
below</link>.
</para>
<section id="ref_guide_runtime_emfactory">
<title>
@ -187,9 +187,8 @@ 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
access the OpenJPA data and query caches and to perform other OpenJPA-specific
operations. See the
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManagerFactory.html">
interface Javadoc</ulink> for details.
</para>
@ -221,7 +220,7 @@ All OpenJPA <classname>EntityManager</classname>s implement the
</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
<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>
@ -249,8 +248,8 @@ extensions this interface contains.
<para>
OpenJPA extends JPA's standard query functionality with the <classname>
org.apache.openjpa.persistence.OpenJPAQuery</classname> interface. See its
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAQuery.html">Javadoc</ulink> for
details on the convenience methods it provides.
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAQuery.html">Javadoc
</ulink> for details on the convenience methods it provides.
</para>
</section>
<section id="ref_guide_runtime_jpaextent">
@ -290,8 +289,8 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
Extent&lt;Magazine&gt; mags = kem.getExtent (Magazine.class, false);
OpenJPAEntityManager kem = OpenJPAPersistence.cast(em);
Extent&lt;Magazine&gt; mags = kem.getExtent(Magazine.class, false);
for (Magazine m : mags)
processMagazine (m);
</programlisting>
@ -352,7 +351,7 @@ OpenJPA.
</seealso>
</indexterm>
<para>
Many of the aforementioned OpenJPA interfaces give you access to a <classname>
Many of the aforementioned OpenJPA interfaces give you access to an <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">
@ -366,14 +365,14 @@ OpenJPA goes one step further, extending <classname>FetchPlan</classname> with
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.
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
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
@ -384,7 +383,7 @@ configuration does not affect the <classname> EntityManagerFactory</classname>.
</para>
<para>
<xref linkend="ref_guide_fetch"/> includes examples using <classname>
FetchPlan</classname> s.
FetchPlan</classname>s.
</para>
</section>
<section id="ref_guide_runtime_openjpapersistence">
@ -515,12 +514,12 @@ locked. You can also use the fetch plan of an individual <classname>Query
<classname>Query</classname>.
</para>
<programlisting>
public LockModeType getReadLockMode ();
public FetchPlan setReadLockMode (LockModeType mode);
public LockModeType getWriteLockMode ();
public FetchPlan setWriteLockMode (LockModeType mode);
long getLockTimeout ();
FetchPlan setLockTimeout (long timeout);
public LockModeType getReadLockMode();
public FetchPlan setReadLockMode(LockModeType mode);
public LockModeType getWriteLockMode();
public FetchPlan setWriteLockMode(LockModeType mode);
long getLockTimeout();
FetchPlan setLockTimeout(long timeout);
</programlisting>
<para>
Controlling locking through these runtime APIs works even during optimistic
@ -538,24 +537,24 @@ import org.apache.openjpa.persistence.*;
...
EntityManager em = ...;
em.getTransaction ().begin ();
em.getTransaction().begin();
// load stock we know we're going to update at write lock mode
Query q = em.createQuery ("select s from Stock s where symbol = :s");
q.setParameter ("s", symbol);
OpenJPAQuery kq = OpenJPAPersistence.cast (q);
FetchPlan fetch = kq.getFetchPlan ();
fetch.setReadLockMode (LockModeType.WRITE);
fetch.setLockTimeout (3000); // 3 seconds
Stock stock = (Stock) q.getSingleResult ();
Query q = em.createQuery("select s from Stock s where symbol = :s");
q.setParameter("s", symbol);
OpenJPAQuery oq = OpenJPAPersistence.cast(q);
FetchPlan fetch = oq.getFetchPlan ();
fetch.setReadLockMode(LockModeType.WRITE);
fetch.setLockTimeout(3000); // 3 seconds
Stock stock = (Stock) q.getSingleResult();
// load an object we don't need locked at none lock mode
fetch = (OpenJPAPersistence.cast (em)).getFetchPlan ();
fetch.setReadLockMode (null);
Market market = em.find (Market.class, marketId);
fetch = OpenJPAPersistence.cast(em).getFetchPlan();
fetch.setReadLockMode(null);
Market market = em.find(Market.class, marketId);
stock.setPrice (market.calculatePrice (stock));
em.getTransaction ().commit ();
stock.setPrice(market.calculatePrice(stock));
em.getTransaction().commit();
</programlisting>
</example>
</section>
@ -576,7 +575,7 @@ 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);
public LockModeType OpenJPAEntityManager.getLockMode(Object pc);
</programlisting>
<para>
Returns the level at which the given object is currently locked.
@ -584,19 +583,19 @@ Returns the level at which the given object is currently locked.
<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>
<methodname>EntityManager.lock(Object, LockModeType)</methodname></ulink>
method, the
<ulink url="../apidocs/org/apache/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);
public void lockAll (Object... pcs, LockModeType mode, long timeout);
public void lockAll (Collection pcs);
public void lockAll (Collection pcs, LockModeType mode, long timeout);
public void lock(Object pc);
public void lock(Object pc, LockModeType mode, long timeout);
public void lockAll(Object... pcs);
public void lockAll(Object... pcs, LockModeType mode, long timeout);
public void lockAll(Collection pcs);
public void lockAll(Collection pcs, LockModeType mode, long timeout);
</programlisting>
<para>
Methods that do not take a lock level or timeout parameter default to the
@ -610,21 +609,21 @@ current fetch plan. The example below demonstrates these methods in action.
import org.apache.openjpa.persistence.*;
// retrieve the lock level of an object
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
OpenJPAEntityManager oem = OpenJPAPersistence.cast(em);
Stock stock = ...;
LockModeType level = kem.getLockMode (stock);
LockModeType level = oem.getLockMode(stock);
if (level == OpenJPAModeType.WRITE) ...
...
kem.setOptimistic (true);
kem.getTransaction ().begin ();
oem.setOptimistic(true);
oem.getTransaction().begin ();
// override default of not locking during an opt trans to lock stock object
kem.lock (stock, LockModeType.WRITE, 1000);
stock.setPrice (market.calculatePrice (stock));
oem.lock(stock, LockModeType.WRITE, 1000);
stock.setPrice(market.calculatePrice(stock));
kem.getTransaction ().commit ();
oem.getTransaction().commit();
</programlisting>
</example>
</section>
@ -658,9 +657,10 @@ own lock manager, or use one of the bundled options:
<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
<classname>o
rg.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>
@ -685,16 +685,6 @@ does not perform any locking at all.
</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>.
@ -839,16 +829,16 @@ 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.
When using the pessimistic 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 pessimistic 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>
@ -888,9 +878,9 @@ 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);
void setSavepoint(String name);
void releaseSavepoint(String name);
void rollbackToSavepoint(String name);
</programlisting>
<para>
To set a savepoint, simply call <methodname>setSavepoint</methodname>, passing
@ -910,9 +900,9 @@ 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
If a savepoint is no longer needed, you can release any resources it is
consuming 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.
@ -930,26 +920,26 @@ import org.apache.openjpa.persistence.*;
...
OpenJPAEntityManager kem = OpenJPAPersistence.cast (em);
kem.getTransaction ().begin ();
OpenJPAEntityManager oem = OpenJPAPersistence.cast(em);
oem.getTransaction().begin();
Magazine mag = kem.find (Magazine.class, id);
mag.setPageCount (300);
kem.setSavepoint ("pages");
Magazine mag = oem.find(Magazine.class, id);
mag.setPageCount(300);
oem.setSavepoint("pages");
mag.setPrice (mag.getPageCount () * pricePerPage);
mag.setPrice(mag.getPageCount() * pricePerPage);
// we decide to release pages since price depends on pages.
kem.releaseSavepoint ("pages");
kem.setSavepoint ("price");
oem.releaseSavepoint("pages");
oem.setSavepoint("price");
mag.setPrice (testPrice);
mag.setPrice(testPrice);
...
// we determine the test price is not good
kem.rollbackToSavepoint ("price");
oem.rollbackToSavepoint("price");
// the price is now restored to mag.getPageCount () * pricePerPage
kem.getTransaction ().commit ();
// the price is now restored to mag.getPageCount() * pricePerPage
oem.getTransaction().commit();
</programlisting>
</example>
</section>
@ -1000,6 +990,7 @@ implements savepoints by issuing a flush to the database.
</itemizedlist>
</section>
</section>
<!--
<section id="ref_guide_enterprise_queryext">
<title>
Query Language Extensions
@ -1020,7 +1011,6 @@ 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
@ -1275,6 +1265,7 @@ Javadoc</ulink> for details.
</itemizedlist>
</section>
</section>
-->
<section id="ref_guide_enterprise_methodql">
<title>
MethodQL
@ -1311,36 +1302,23 @@ import org.apache.openjpa.persistence.*;
// the class is in the candidate class' package or in the query imports, you
// can omit the package; if the method is in the candidate class, you can omit
// the class name and just specify the method name
OpenJPAEntityManager kem = OpenJPAPersistence.cast (emf);
OpenJPAQuery q = kem.createQuery ("openjpa.MethodQL", "com.xyz.Finder.getByName");
OpenJPAEntityManager oem = OpenJPAPersistence.cast(emf);
OpenJPAQuery q = oem.createQuery("openjpa.MethodQL", "com.xyz.Finder.getByName");
// set the type of objects that the method returns
q.setResultClass (Person.class);
q.setResultClass(Person.class);
// parameters are passed the same way as in standard queries
q.setParameter ("firstName", "Fred").setParameter ("lastName", "Lucas");
q.setParameter("firstName", "Fred").setParameter("lastName", "Lucas");
// this executes your method to get the results
List results = q.getResultList ();
List results = q.getResultList();
</programlisting>
<para>
For datastore queries, the method must have the following signature:
</para>
<programlisting>
public static
<ulink url="../apidocs/org/apache/openjpa/lib/rop/ResultObjectProvider.html">ResultObjectProvider
</ulink>
xxx(
<ulink url="../apidocs/org/apache/openjpa/kernel/StoreContext.html">StoreContext
</ulink>
ctx,
<ulink url="../apidocs/org/apache/openjpa/meta/ClassMetaData.html">ClassMetaData
</ulink>
meta, boolean subclasses, Map params,
<ulink url="../apidocs/org/apache/openjpa/kernel/FetchConfiguration.html">FetchConfiguration
</ulink>
fetch)
public static <ulink url="../apidocs/org/apache/openjpa/lib/rop/ResultObjectProvider.html">ResultObjectProvider</ulink> xxx(<ulink url="../apidocs/org/apache/openjpa/kernel/StoreContext.html">StoreContext</ulink> ctx, <ulink url="../apidocs/org/apache/openjpa/meta/ClassMetaData.html">ClassMetaData</ulink> meta, boolean subclasses, Map params, <ulink url="../apidocs/org/apache/openjpa/kernel/FetchConfiguration.html">FetchConfiguration </ulink> fetch)
</programlisting>
<para>
The returned result object provider should produce objects of the candidate
@ -1354,24 +1332,16 @@ In-memory execution is slightly different, taking in one object at a time and
returning a boolean on whether the object matches the query:
</para>
<programlisting>
public static boolean xxx(
<ulink url="../apidocs/org/apache/openjpa/kernel/StoreContext.html">StoreContext
</ulink>
ctx,
<ulink url="../apidocs/org/apache/openjpa/meta/ClassMetaData.html">ClassMetaData
</ulink>
meta,
boolean subclasses, Object obj, Map params,
<ulink url="../apidocs/org/apache/openjpa/kernel/FetchConfiguration.html">FetchConfiguration
</ulink>
fetch)
public static boolean xxx(<ulink url="../apidocs/org/apache/openjpa/kernel/StoreContext.html">StoreContext</ulink> ctx, <ulink url="../apidocs/org/apache/openjpa/meta/ClassMetaData.html">ClassMetaData</ulink> meta, boolean subclasses, Object obj, Map params, <ulink url="../apidocs/org/apache/openjpa/kernel/FetchConfiguration.html">FetchConfiguration</ulink> fetch)
</programlisting>
<para>
In both method versions, the given <literal>params</literal> map contains the
names and values of all the parameters for the query.
</para>
</section>
<!--
</section>
-->
<section id="ref_guide_sequence">
<title>
Generators
@ -1398,7 +1368,7 @@ including the current persistence environment, the JDBC <classname>DataSource
<ulink url="../apidocs/org/apache/openjpa/jdbc/kernel/AbstractJDBCSeq.html">
<classname>org.apache.openjpa.jdbc.kernel.AbstractJDBCSeq</classname></ulink>
helps you create custom JDBC-based sequences. OpenJPA also supplies the
following built-in <classname>Seq</classname> s:
following built-in <classname>Seq</classname>s:
</para>
<itemizedlist>
<listitem>
@ -1418,11 +1388,10 @@ alias for the
class. The <classname>TableJDBCSeq</classname> uses a special single-row table
to store a global sequence number. If the table does not already exist, it is
created the first time you run the
<link linkend="ref_guide_mapping_mappingtool"> mapping tool</link>'s on a class
that requires it. You can also use the class' <methodname>main</methodname>
method or the <literal>sequencetable</literal> shell/bat script to manipulate
the table; see the <methodname>TableJDBCSeq.main</methodname> method Javadoc for
usage details.
<link linkend="ref_guide_mapping_mappingtool">mapping tool</link> on a class
that requires it. You can also use the class's <methodname>main</methodname>
method to manipulate the table; see the
<methodname>TableJDBCSeq.main</methodname> method Javadoc for usage details.
</para>
<para>
This <classname>Seq</classname> has the following properties:
@ -1480,8 +1449,8 @@ OPENJPA_SEQUENCES_TABLE</literal>. It also adds the following properties:
<listitem>
<para>
<literal>IgnoreUnmapped</literal>: Whether to ignore unmapped base classes, and
instead use one row per least-derived mapped class. Defaults to <literal>false
</literal>.
instead use one row per least-derived mapped class. Defaults to <literal>
false</literal>.
</para>
</listitem>
<listitem>
@ -1496,8 +1465,7 @@ primary key value of each row, rather than the full class name. Defaults to
As with the <classname>TableJDBCSeq</classname>, the <classname>
ClassTableJDBCSeq</classname> creates its table automatically during mapping
tool runs. However, you can manually manipulate the table through the class'
<methodname>main</methodname> method, or through the <literal>
classsequencetable</literal> shell/bat script. See the Javadoc for the
<methodname>main</methodname> method. See the Javadoc for the
<methodname> ClassTableJDBCSeq.main</methodname> method for usage details.
</para>
</listitem>
@ -1523,8 +1491,7 @@ rather than a fixed pattern of one row per class. Its table defaults to
<itemizedlist>
<listitem>
<para>
<literal>PrimaryKeyValue</literal>: The primary key value used by this
instance.
<literal>PrimaryKeyValue</literal>: The primary key value used by this instance.
</para>
</listitem>
</itemizedlist>
@ -1532,9 +1499,8 @@ instance.
As with the <classname>TableJDBCSeq</classname>, the <classname>
ValueTableJDBCSeq</classname> creates its table automatically during mapping
tool runs. However, you can manually manipulate the table through the class'
<methodname>main</methodname> method, or through the <literal>
valuesequencetable</literal> shell/bat script. See the Javadoc for the
<methodname> ValueTableJDBCSeq.main</methodname> method for usage details.
<methodname>main</methodname> method. See the Javadoc for the
<methodname>ValueTableJDBCSeq.main</methodname> method for usage details.
</para>
</listitem>
<listitem>
@ -1573,8 +1539,7 @@ properties:
</listitem>
<listitem>
<para>
<literal>Increment</literal>: The amount the sequence increments. Defaults to
1.
<literal>Increment</literal>: The amount the sequence increments. Defaults to 1.
</para>
</listitem>
<listitem>
@ -1610,7 +1575,7 @@ You can use JPA <literal>SequenceGenerator</literal>s to describe any built-in
implementation. Set the <literal>sequenceName</literal> attribute to a plugin
string describing your choice. See
<xref linkend="jpa_overview_mapping_sequence"/> in the JPA Overview for
details on defining <literal>SequenceGenerator</literal> s.
details on defining <literal>SequenceGenerator</literal>s.
</para>
<para>
See <xref linkend="ref_guide_conf_plugins"/> for plugin string formatting.
@ -1622,8 +1587,8 @@ See <xref linkend="ref_guide_conf_plugins"/> for plugin string formatting.
<programlisting>
@Entity
@Table(name="AUTO")
public class Author
{
public class Author {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="AuthorSeq")
@SequenceGenerator(name="AuthorSeq" sequence="table(Table=AUTO_SEQ, Increment=100)")
@ -1685,7 +1650,7 @@ OpenJPA allows you to access named generators at runtime through the
<methodname>OpenJPAEntityManager.getNamedGenerator</methodname> method:
</para>
<programlisting>
public Generator getNamedGenerator (String name);
public Generator getNamedGenerator(String name);
</programlisting>
<para>
The returned
@ -1728,8 +1693,8 @@ and more. Where appropriate, event notifications include the set of
persistence-capable objects participating in the transaction.
</para>
<programlisting>
public void addTransactionListener (Object listener);
public void removeTransactionListener (Object listener);
public void addTransactionListener(Object listener);
public void removeTransactionListener(Object listener);
</programlisting>
<para>
These <classname>OpenJPAEntityManager</classname> methods allow you to add and

View File

@ -68,9 +68,7 @@ by OpenJPA.
6.0
</entry>
<entry colname="drivname">
Borland JDataStore
Borland JDataStore
</entry>
<entry colname="drivversion">
6.0
@ -84,9 +82,7 @@ by OpenJPA.
8.1
</entry>
<entry colname="drivname">
IBM DB2 JDBC Universal Driver
IBM DB2 JDBC Universal Driver
</entry>
<entry colname="drivversion">
1.0.581
@ -100,9 +96,7 @@ by OpenJPA.
8.62
</entry>
<entry colname="drivname">
Empress Category 2 JDBC Driver
Empress Category 2 JDBC Driver
</entry>
<entry colname="drivversion">
8.62
@ -172,9 +166,7 @@ by OpenJPA.
9.0 (a.k.a. "2000")
</entry>
<entry colname="drivname">
DataDirect SequeLink
DataDirect SequeLink
</entry>
<entry colname="drivversion">
5.4.0038
@ -185,9 +177,7 @@ by OpenJPA.
Microsoft SQL Server
</entry>
<entry colname="dbversion">
9.00.1399 (SQL Server 2005)
9.00.1399 (SQL Server 2005)
</entry>
<entry colname="drivname">
SQLServer
@ -204,9 +194,7 @@ by OpenJPA.
7.0
</entry>
<entry colname="drivname">
DataDirect SequeLink
DataDirect SequeLink
</entry>
<entry colname="drivversion">
5.4.0038
@ -270,9 +258,7 @@ by OpenJPA.
</row>
<row>
<entry colname="dbname">
Sybase Adaptive Server Enterprise
Sybase Adaptive Server Enterprise
</entry>
<entry colname="dbversion">
12.5
@ -318,19 +304,20 @@ openjpa.ConnectionURL: jdbc:interbase://SERVER_NAME:SERVER_PORT/DB_PATH
<title>
Known issues with Interbase
</title>
<para>
<itemizedlist><listitem><para> Interbase does not support record locking, so
<itemizedlist>
<listitem>
<para>
Interbase does not support record locking, so
datastore transactions cannot use the pessimistic lock manager.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Interbase does not support the <literal>LOWER</literal>, <literal>SUBSTRING
</literal>, or <literal>INSTR</literal> SQL functions>
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_jdatastore">
@ -364,24 +351,24 @@ openjpa.ConnectionURL: jdbc:db2://SERVER_NAME:SERVER_PORT/DB_NAME
<title>
Known issues with DB2
</title>
<para>
<itemizedlist><listitem><para>Floats and doubles may lose precision when
stored.
</para>
</listitem>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
Floats and doubles may lose precision when stored.
</para>
</listitem>
<listitem>
<para>
Empty char values are stored as NULL.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Fields of type BLOB and CLOB are limited to 1M. This number can be increased by
extending <classname>DB2Dictionary</classname>.
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_empress">
@ -401,19 +388,20 @@ openjpa.ConnectionURL: jdbc:empress://SERVER=yourserver;PORT=6322;DATABASE=yourd
<title>
Known issues with Empress
</title>
<para>
<itemizedlist><listitem><para> Empress enforces pessimistic semantics (lock on
<itemizedlist>
<listitem>
<para>
Empress enforces pessimistic semantics (lock on
read) when not using <literal>AllowConcurrentRead</literal> property (which
bypasses row locking) for <classname>EmpressDictionary</classname>.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Only the category 2 non-local driver is supported.
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_hypersonic">
@ -433,20 +421,15 @@ openjpa.ConnectionURL: jdbc:hsqldb:DB_NAME
<title>
Known issues with Hypersonic
</title>
<para>
<itemizedlist><listitem><para> Hypersonic does not properly support foreign key
constraints.
</para>
</listitem>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
Hypersonic does not support pessimistic locking, so non-optimistic transactions
will fail unless the <literal>SimulateLocking</literal> property is set for the
<link linkend="openjpa.jdbc.DBDictionary"> openjpa.jdbc.DBDictionary</link>
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_firebird">
@ -466,24 +449,19 @@ openjpa.ConnectionURL: jdbc:firebirdsql://SERVER_NAME:SERVER_PORT/DB_PATH
<title>
Known issues with Firebird
</title>
<para>
<itemizedlist><listitem><para> The Firebird JDBC driver does not have proper
support for batch updates, so batch updates are disabled.
</para>
</listitem>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
Firebird does not support auto-increment columns.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Firebird does not support the <literal>LOWER</literal>, <literal>SUBSTRING
</literal>, or <literal>INSTR</literal> SQL functions.
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_informix">
@ -504,12 +482,13 @@ openjpa.ConnectionURL: \
<title>
Known issues with Informix
</title>
<para>
<itemizedlist><listitem><para> none
</para>
</listitem>
</itemizedlist>
</para>
<itemizedlist>
<listitem>
<para>
None
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_intersystems_cache">
@ -529,13 +508,14 @@ openjpa.ConnectionURL: jdbc:Cache://SERVER_NAME:SERVER_PORT/DB_NAME
<title>
Known issues with InterSystems Cache
</title>
<para>
<itemizedlist><listitem><para> Support for Cache is done via SQL access over
JDBC, not through their object database APIs.
</para>
</listitem>
</itemizedlist>
</para>
<itemizedlist>
<listitem>
<para>
Support for Cache is done via SQL access over JDBC, not through their object
database APIs.
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_access">
@ -555,13 +535,13 @@ openjpa.ConnectionURL: jdbc:sequelink://SERVER_NAME:SERVER_PORT
<title>
Known issues with Microsoft Access
</title>
<para>
<itemizedlist><listitem><para>Using the Sun JDBC-ODBC bridge to connect is not
supported.
</para>
</listitem>
</itemizedlist>
</para>
<itemizedlist>
<listitem>
<para>
Using the Sun JDBC-ODBC bridge to connect is not supported.
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_sqlserver">
@ -582,42 +562,43 @@ openjpa.ConnectionURL: \
<title>
Known issues with SQL Server
</title>
<para>
<itemizedlist><listitem><para> SQL Server date fields are accurate only to the
nearest 3 milliseconds, possibly resulting in precision loss in stored dates.
</para>
</listitem>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
SQL Server date fields are accurate only to the nearest 3 milliseconds,
possibly resulting in precision loss in stored dates.
</para>
</listitem>
<listitem>
<para>
The ConnectionURL must always contain the " <literal>selectMethod=cursor
</literal> " string.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Adding <literal>sendStringParametersAsUnicode=false</literal> to the
ConnectionURL may significantly increase performance.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
The Microsoft SQL Server driver only emulates batch updates. The DataDirect JDBC
driver has true support for batch updates, and may result in a significant
performance gain.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Floats and doubles may lose precision when stored.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
<literal>TEXT</literal> columns cannot be used in queries.
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_foxpro">
@ -637,13 +618,13 @@ openjpa.ConnectionURL: jdbc:sequelink://SERVER_NAME:SERVER_PORT
<title>
Known issues with Microsoft FoxPro
</title>
<para>
<itemizedlist><listitem><para>Using the Sun JDBC-ODBC bridge to connect is not
supported.
</para>
</listitem>
</itemizedlist>
</para>
<itemizedlist>
<listitem>
<para>
Using the Sun JDBC-ODBC bridge to connect is not supported.
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_mysql">
@ -663,52 +644,52 @@ openjpa.ConnectionURL: jdbc:mysql://SERVER_NAME/DB_NAME
<title>
Known issues with MySQL
</title>
<para>
<itemizedlist><listitem><para> The default table types that MySQL uses do not
support transactions, which will prevent OpenJPA from being able to roll back
transactions. Use the <literal>InnoDB</literal> table type for any tables that
OpenJPA will access.
</para>
</listitem>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
The default table types that MySQL uses do not support transactions, which will
prevent OpenJPA from being able to roll back transactions. Use the
<literal>InnoDB</literal> table type for any tables that OpenJPA will access.
</para>
</listitem>
<listitem>
<para>
MySQL does not support sub-selects in versions prior to 4.1, and are disabled by
default. Some operations (such as the <function>isEmpty()</function> method in a
query) will fail due to this. If you are using MySQL 4.1 or later, you can lift
this restriction by setting the <literal>SupportsSubselect=true</literal>
parameter of the <link linkend="openjpa.jdbc.DBDictionary">
openjpa.jdbc.DBDictionary</link> property.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Rollback due to database error or optimistic lock violation is not supported
unless the table type is one of the MySQL transactional types. Explicit calls to
<function>rollback()</function> before a transaction has been committed,
however, are always supported.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Floats and doubles may lose precision when stored in some datastores.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
When storing a field of type <classname>java.math.BigDecimal</classname>, some
datastores will add extraneous trailing 0 characters, causing an equality
mismatch between the field that is stored and the field that is retrieved.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Some version of the MySQL JDBC driver have a bug that prevents OpenJPA from
being able to interrogate the database for foreign keys. Version 3.0.14 (or
higher) of the MySQL driver is required in order to get around this bug.
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_oracle">
@ -740,16 +721,9 @@ the most intensive queries.
Using Oracle Hints
</title>
<programlisting>
Query query = pm.createQuery (...);
query.addExtension (org.apache.openjpa.jdbc.sql.OracleDictionary.SELECT_HINT,
"/*+ first_rows(100) */");
List results = (List) query.execute ();
</programlisting>
<programlisting>
Query query = em.createQuery (...);
query.setHint (org.apache.openjpa.jdbc.sql.OracleDictionary.SELECT_HINT,
"/*+ first_rows(100) */");
List results = query.getResultList ();
Query query = em.createQuery(...);
query.setHint("openjpa.hint.OracleSelectHint", "/*+ first_rows(100) */");
List results = query.getResultList();
</programlisting>
</example>
</section>
@ -757,49 +731,49 @@ List results = query.getResultList ();
<title>
Known issues with Oracle
</title>
<para>
<itemizedlist><listitem><para> The Oracle JDBC driver has significant
differences between different versions. It is important to use the officially
supported version of the driver (10.2.0.1.0), which is backward compatible with
previous versions of the Oracle server. It can be downloaded from
<itemizedlist>
<listitem>
<para>
The Oracle JDBC driver has significant differences between different versions.
It is important to use the officially supported version of the driver
(10.2.0.1.0), which is backward compatible with previous versions of the Oracle
server. It can be downloaded from
<ulink url="http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc101040.html">
http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc101040.html
</ulink>.
</para>
</listitem>
<listitem>
<para>
http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc101040.html</ulink>.
</para>
</listitem>
<listitem>
<para>
For VARCHAR fields, <literal>null</literal> and a blank string are equivalent.
This means that an object that stores a null string field will have it get read
back as a blank string.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Oracle corp's JDBC driver for Oracle has only limited support for batch updates.
The result for OpenJPA is that in some cases, the exact object that failed an
optimistic lock check cannot be determined, and OpenJPA will throw an
<classname>OptimisticVerificationException</classname> with more failed objects
than actually failed.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Oracle cannot store numbers with more than 38 digits in numeric columns.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Floats and doubles may lose precision when stored.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
CLOB columns cannot be used in queries.
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_pointbase">
@ -820,14 +794,15 @@ openjpa.ConnectionURL: \
<title>
Known issues with Pointbase
</title>
<para>
<itemizedlist><listitem><para> Fields of type BLOB and CLOB are limited to 1M.
This number can be increased by extending <classname>PointbaseDictionary
</classname>.
</para>
</listitem>
</itemizedlist>
</para>
<itemizedlist>
<listitem>
<para>
Fields of type BLOB and CLOB are limited to 1M. Set the <literal>BlobTypeName
</literal> and/or <literal>ClobTypeName</literal> properties of the
<literal>openjpa.jdbc.DBDictionary</literal> setting to override.
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_postgresql">
@ -847,23 +822,23 @@ openjpa.ConnectionURL: jdbc:postgresql://SERVER_NAME:5432/DB_NAME
<title>
Known issues with PostgreSQL
</title>
<para>
<itemizedlist><listitem><para> Floats and doubles may lose precision when
stored.
</para>
</listitem>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
Floats and doubles may lose precision when stored.
</para>
</listitem>
<listitem>
<para>
PostgreSQL cannot store very low and very high dates.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Empty string/char values are stored as NULL.
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
<section id="dbsupport_sybase">
@ -884,35 +859,36 @@ openjpa.ConnectionURL: \
<title>
Known issues with Sybase
</title>
<para>
<itemizedlist><listitem><para> The " <literal>DYNAMIC_PREPARE</literal> "
parameter of the Sybase JDBC driver cannot be used with OpenJPA.
</para>
</listitem>
<listitem>
<para>
<itemizedlist>
<listitem>
<para>
The "<literal>DYNAMIC_PREPARE</literal>" parameter of the Sybase JDBC driver
cannot be used with OpenJPA.
</para>
</listitem>
<listitem>
<para>
Datastore locking cannot be used when manipulating many-to-many relations using
the default OpenJPA schema created by the schematool, unless an auto-increment
primary key field is manually added to the table.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
Persisting a zero-length string results in a string with a single space
characted being returned from Sybase, Inc.'s JDBC driver.
</para>
</listitem>
<listitem>
<para>
</para>
</listitem>
<listitem>
<para>
The <literal>BE_AS_JDBC_COMPLIANT_AS_POSSIBLE</literal> is required in order to
use datastore (pessimistic) locking. Failure to set this property may lead to
obscure errors like " <literal>FOR UPDATE can not be used in a SELECT which is
not part of the declaration of a cursor or which is not inside a stored
procedure.</literal> ".
</para>
</listitem>
</itemizedlist>
</para>
</para>
</listitem>
</itemizedlist>
</section>
</section>
</appendix>