Split up the documentation into multiple chunks for easier management.

git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@433761 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Marc Prud'hommeaux 2006-08-22 21:28:53 +00:00
parent d13c9fa4f6
commit ac98ba5c80
33 changed files with 33912 additions and 33818 deletions

View File

@ -47,13 +47,21 @@
basedir="${project.basedir}/src/doc/manual"
destdir="${project.basedir}/target/filtered-site/resources/manual"
style="manual-xhtml.xsl"
classpathref="maven.runtime.classpath"/>
classpathref="maven.runtime.classpath">
<factory name="org.apache.xalan.processor.TransformerFactoryImpl">
<attribute name="http://xml.apache.org/xalan/features/optimize" value="true"/>
</factory>
</style>
<style includes="**/manual.xml"
force="true"
basedir="${project.basedir}/src/doc/manual"
destdir="${project.basedir}/target/filtered-site/resources/manual"
style="manual-xhtml-chunk.xsl"
classpathref="maven.runtime.classpath"/>
classpathref="maven.runtime.classpath">
<factory name="org.apache.xalan.processor.TransformerFactoryImpl">
<attribute name="http://xml.apache.org/xalan/features/optimize" value="true"/>
</factory>
</style>
</tasks>
</configuration>
<goals>

View File

@ -0,0 +1,196 @@
<chapter id="jpa_overview_arch">
<title>EJB Persistence Architecture</title>
<indexterm zone="jpa_overview_arch">
<primary>EJB</primary>
<secondary>architecture</secondary>
</indexterm>
<para>
The diagram below illustrates the relationships between the primary
components of the EJB architecture.
</para>
<mediaobject>
<imageobject>
<!-- PNG image data 400 x 256 (see README) -->
<imagedata fileref="img/jpa-arch.png" width="267px"/>
</imageobject>
<textobject>
<phrase>EJB architecture</phrase>
</textobject>
</mediaobject>
<note>
<para>
A number of the depicted interfaces are only required outside of
an EJB3-compliant application server. In an application server,
<classname>EntityManager</classname> instances are typically injected,
rendering the <classname>EntityManagerFactory</classname> unnecessary.
Also, transactions within an application server
are handled using standard application server transaction controls.
Thus, the <classname>EntityTransaction</classname> also goes unused.
</para>
</note>
<itemizedlist>
<listitem>
<para><indexterm><primary>Persistence</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_persistence"><classname>Persistence</classname></link></emphasis>:
The <classname>javax.persistence.Persistence</classname> class
contains static helper methods to obtain
<classname>EntityManagerFactory</classname> instances in a
vendor-neutral fashion.
</para>
</listitem>
<listitem>
<para><indexterm><primary>EntityManagerFactory</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_emfactory"><classname>EntityManagerFactory</classname></link></emphasis>: The <classname>javax.persistence.EntityManagerFactory
</classname> class is a factory for <classname>
EntityManager</classname>s.
</para>
</listitem>
<listitem>
<para><indexterm><primary>EntityManager</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_em"><classname>EntityManager</classname></link></emphasis>:
The <classname>javax.persistence.EntityManager</classname> is the
primary EJB persistence interface used by applications.
Each <classname>EntityManager</classname> manages a set of
persistent objects, and has APIs to insert new objects and delete
existing ones. When used outside the container, there is a
one-to-one relationship between an
<classname>EntityManager</classname> and an <classname>
EntityTransaction</classname>. <classname>
EntityManager</classname>s also act as factories for
<classname>Query</classname> instances.
</para>
</listitem>
<listitem>
<para><indexterm><primary>entity</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_pc"><classname>Entity</classname></link></emphasis>:
Entites are persistent objects that represent datastore records.
</para>
</listitem>
<listitem>
<para><indexterm><primary>EntityTransaction</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_trans"><classname>EntityTransaction</classname></link></emphasis>:
Each <classname>EntityManager</classname> has a one-to-one
relation with a single
<classname>javax.persistence.EntityTransaction</classname>.
<classname>EntityTransaction</classname>s allow operations on
persistent data to be grouped into units of work that either
completely succeed or completely fail, leaving the datastore
in its original state. These all-or-nothing operations are
important for maintaining data integrity.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Query</primary></indexterm><indexterm><primary>EJB3 Persistence Query Language</primary><see>JPQL</see></indexterm><indexterm><primary>JPQL</primary></indexterm><indexterm><primary>EJB</primary><secondary>query language</secondary><see>JPQL</see></indexterm><indexterm><primary>Structured Query Language</primary><see>SQL</see></indexterm><indexterm><primary>SQL</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_query"><classname>Query</classname></link></emphasis>: The
<classname>javax.persistence.Query</classname> interface is
implemented by each EJB vendor to find persistent objects
that meet certain criteria. EJB standardizes support
for queries using both the EJB Query Language (JPQL) and
the Structured Query Language (SQL). You obtain
<classname>Query</classname> instances from an
<classname>EntityManager</classname>.
</para>
</listitem>
</itemizedlist>
<para>
The example below illustrates how the EJB interfaces interact to
execute an JPQL query and update persistent objects. The example
assumes execution outside a container.
</para>
<example id="jpa_overview_arch_interact_outside">
<title>Interaction of Interfaces Outside Container</title>
<programlisting format="linespecific">
// get an EntityManagerFactory using the Persistence class; typically
// the factory is cached for easy repeated use
EntityManagerFactory factory = Persistence.createEntityManagerFactory (null);
// get an EntityManager from the factory
EntityManager em = factory.createEntityManager (PersistenceContextType.EXTENDED);
// updates take place within transactions
EntityTransaction tx = em.getTransaction ();
tx.begin ();
// query for all employees who work in our research division
// and put in over 40 hours a week average
Query query = em.createQuery ("select e from Employee e where "
+ "e.division.name = 'Research' AND e.avgHours &gt; 40");
List results = query.getResultList ();
// give all those hard-working employees a raise
for (Object res : results)
{
Employee emp = (Employee) res;
emp.setSalary (emp.getSalary () * 1.1);
}
// commit the updates and free resources
tx.commit ();
em.close ();
factory.close ();
</programlisting>
</example>
<para>
Within a container, the <classname>EntityManager</classname> will be
injected and transactional handled declaratively. Thus, the in-container
version of the example consists entirely of business logic:
</para>
<example id="jpa_overview_arch_interact_inside">
<title>Interaction of Interfaces Inside Container</title>
<programlisting format="linespecific">
// query for all employees who work in our research division
// and put in over 40 hours a week average - note that the EntityManager em
// is injected using a @Resource annotation
Query query = em.createQuery ("select e from Employee e where "
+ "e.division.name = 'Research' and e.avgHours &gt; 40");
List results = query.getResultList ();
// give all those hard-working employees a raise
for (Object res : results)
{
emp = (Employee) res;
emp.setSalary (emp.getSalary () * 1.1);
}
</programlisting>
</example>
<para>
The remainder of this document explores the EJB interfaces in
detail. We present them in roughly the order that you will use them as you
develop your application.
</para>
<section id="jpa_overview_arch_exceptions">
<title>EJB Exceptions</title>
<indexterm zone="jpa_overview_arch_exceptions">
<primary>EJB</primary>
<secondary>exceptions</secondary>
<seealso>exceptions</seealso>
</indexterm>
<indexterm>
<primary>exceptions</primary>
<secondary>EJB</secondary>
</indexterm>
<mediaobject>
<imageobject>
<!-- PNG image data, 427 x 355 (see README) -->
<imagedata fileref="img/jpa-exceptions.png" width="285px"/>
</imageobject>
<textobject>
<phrase>EJB persistence exception architecture</phrase>
</textobject>
</mediaobject>
<para>
The diagram above depicts the EJB persistence exception architecture.
All exceptions are unchecked. EJB persistence uses
standard exceptions where appropriate, most notably <classname>
IllegalArgumentException</classname>s and <classname>
IllegalStateException</classname>s. The specification also provides
a few EJB-specific exceptions in the <literal>javax.persistence
</literal> package. These exceptions should be self-explanatory. See
the <ulink url="http://java.sun.com/javaee/5/docs/api">Javadoc</ulink> for
additional details on EJB exceptions.
</para>
<note>
<para>
All exceptions thrown by OpenJPA implement
<ulink url="../apidocs/org/apache/openjpa/util/ExceptionInfo.html"><classname>
org.apache.openjpa.util.ExceptionInfo</classname></ulink> to provide you with
additional error information.
</para>
</note>
</section>
</chapter>

View File

@ -0,0 +1,18 @@
<chapter id="jpa_overview_conclusion">
<title>Conclusion</title>
<para>
This concludes our overview of the EJB persistence specification. The
<link linkend="jpa_tutorials_intro">OpenJPA EJB Tutorials</link>
continue your EJB education with step-by-step instructions for
building simple EJB persistence applications. The
<link linkend="ref_guide_intro">OpenJPA Reference Guide</link> contains
detailed documentation on all aspects of the OpenJPA EJB persistence
implementation and core development tools.
<!-- ### JDO2MIG
Finally,
the <link linkend="gui_intro">Workbench Guide</link> teaches you how to
use the OpenJPA Development Workbench for GUI-driven development.
-->
</para>
</chapter>

View File

@ -0,0 +1,714 @@
<chapter id="jpa_overview_em">
<title>EntityManager</title>
<indexterm zone="jpa_overview_em">
<primary>EntityManager</primary>
</indexterm>
<mediaobject>
<imageobject>
<!-- PNG image data, 283 x 391 (see README) -->
<imagedata fileref="img/entitymanager.png" width="189px"/>
</imageobject>
</mediaobject>
<para>
The diagram above presents an overview of the
<classname>EntityManager</classname> interface. For a complete
treatment of the <classname>EntityManager</classname> API, see the
<ulink url="jdo-javadoc/javax/jdo/EntityManager.html">
Javadoc</ulink> documentation. Methods whose parameter signatures consist
of an ellipsis (...) are overloaded to take multiple parameter types.
</para>
<note>
<para>
OpenJPA extends the standard <classname>EntityManager</classname>
interface with the
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><classname>org.apache.openjpa.persistence.OpenJPAEntityManager</classname></ulink>
interface to provide additional functionality.
</para>
</note>
<para>
The <classname>EntityManager</classname> is the primary interface
used by application developers to interact with the EJB persistence runtime.
The methods of the <classname>EntityManager</classname> can be
divided into the following functional categories:
</para>
<itemizedlist>
<listitem>
<para><classname>Transaction</classname> association.</para>
</listitem>
<listitem>
<para>Entity lifecycle management.</para>
</listitem>
<listitem>
<para>Entity identity management.</para>
</listitem>
<listitem>
<para>Cache management.</para>
</listitem>
<listitem>
<para><classname>Query</classname> factory.</para>
</listitem>
<listitem>
<para>Closing.</para>
</listitem>
</itemizedlist>
<section id="jpa_overview_em_trans">
<title>Transaction Association</title>
<indexterm zone="jpa_overview_em_trans">
<primary>EntityManager</primary>
<secondary>obtaining the Transaction</secondary>
<seealso>transactions</seealso>
</indexterm>
<indexterm zone="jpa_overview_em_trans">
<primary>Transaction</primary>
<secondary>obtaining from EntityManager</secondary>
</indexterm>
<programlisting format="linespecific">
public EntityTransaction getTransaction ();
</programlisting>
<para>
Every <classname>EntityManager</classname> has a one-to-one
relation with an <link linkend="jpa_overview_trans"><classname>EntityTransaction</classname></link> instance. In
fact, many vendors use a single class to implement both
the <classname>EntityManager</classname> and
<classname>EntityTransaction</classname> interfaces. If your
application requires multiple concurrent transactions, you will
use multiple <classname>EntityManager</classname>s.
</para>
<para>
You can retrieve the <classname>EntityTransaction</classname>
associated with an <classname>EntityManager</classname> through the
<methodname>getTransaction</methodname> method. Note that most
most EJB persistence implementations can integrate with an application
server's managed transactions. If you take advantage of this feature,
you will control transactions by declarative demarcation or through
the Java Transaction API (JTA) rather than through the
<classname>EntityTransaction</classname>.
</para>
</section>
<section id="jpa_overview_em_lifecycle">
<title>Entity Lifecycle Management</title>
<indexterm zone="jpa_overview_em_lifecycle">
<primary>EntityManager</primary>
<secondary>lifecycle operations</secondary>
</indexterm>
<para><classname>EntityManager</classname>s perform several actions
that affect the lifecycle state of entity instances.
</para>
<programlisting format="linespecific">
public void persist (Object entity);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>persist</secondary></indexterm><indexterm><primary>persist</primary><seealso>EntityManager</seealso></indexterm><indexterm><primary>persistent objects</primary><secondary>persisting</secondary></indexterm>
Transitions new instances to managed. On the next flush or commit,
the newly persisted instances will be inserted into the datastore.
</para>
<para>
For a given entity <literal>A</literal>, the <methodname>persist
</methodname> method behaves as follows:
</para>
<itemizedlist>
<listitem>
<para>
If <literal>A</literal> is a new entity, it becomes managed.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is an existing managed entity, it is
ignored. However, the persist operation cascades as
defined below.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is a removed entity, it becomes managed.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is a detached entity, an
<classname>IllegalArgumentException</classname> is thrown.
</para>
</listitem>
<listitem>
<para>
The persist operation recurses on all relation fields of
<literal>A</literal> whose
<link linkend="jpa_overview_meta_cascade">cascades</link>
include <literal>CascadeType.PERSIST</literal>.
</para>
</listitem>
</itemizedlist>
<para>
This action can only be used in the context of an active transaction.
</para>
<programlisting format="linespecific">
public void remove (Object entity);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>remove</secondary></indexterm><indexterm><primary>remove</primary><seealso>EntityManager</seealso></indexterm><indexterm><primary>persistent objects</primary><secondary>deleting</secondary></indexterm>
Transitions managed instances to removed. The instances will be
deleted from the datastore on the next flush or commit. Accessing
a removed entity has undefined results.
</para>
<para>
For a given entity <literal>A</literal>, the <methodname>remove
</methodname> method behaves as follows:
</para>
<itemizedlist>
<listitem>
<para>
If <literal>A</literal> is a new entity, it is ignored.
However, the remove operation cascades as defined below.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is an existing managed entity, it
becomes removed.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is a removed entity, it is ignored.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is a detached entity, an
<classname>IllegalArgumentException</classname> is thrown.
</para>
</listitem>
<listitem>
<para>
The remove operation recurses on all relation fields of
<literal>A</literal> whose
<link linkend="jpa_overview_meta_cascade">cascades</link>
include <literal>CascadeType.REMOVE</literal>.
</para>
</listitem>
</itemizedlist>
<para>
This action can only be used in the context of an active transaction.
</para>
<programlisting format="linespecific">
public void refresh (Object entity);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>refresh</secondary></indexterm><indexterm><primary>refresh</primary><seealso>EntityManager</seealso></indexterm><indexterm><primary>persistent objects</primary><secondary>refreshing state</secondary></indexterm><indexterm><primary>transactions</primary><secondary>optimistic</secondary></indexterm>
Use the <methodname>refresh</methodname> action to make sure
the persistent state of an instance is synchronized with the
values in the datastore. <methodname>refresh</methodname>
is intended for long-running optimistic transactions in
which there is a danger of seeing stale data.
</para>
<para>
For a given entity <literal>A</literal>, the <methodname>refresh
</methodname> method behaves as follows:
</para>
<itemizedlist>
<listitem>
<para>
If <literal>A</literal> is a new entity, it is ignored.
However, the remove operation cascades as defined below.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is an existing managed entity, its
state is refreshed from the datastore.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is a removed entity, it is ignored.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is a detached entity, an
<classname>IllegalArgumentException</classname> is thrown.
</para>
</listitem>
<listitem>
<para>
The refresh operation recurses on all relation fields of
<literal>A</literal> whose
<link linkend="jpa_overview_meta_cascade">cascades</link>
include <literal>CascadeType.REFRESH</literal>.
</para>
</listitem>
</itemizedlist>
<programlisting format="linespecific">
public Object merge (Object entity);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>merge</secondary><seealso>detachment</seealso></indexterm><indexterm><primary>detachment</primary><secondary>EJB</secondary></indexterm><indexterm><primary>merge</primary><seealso>detachment</seealso></indexterm><indexterm><primary>data transfer object</primary></indexterm><indexterm><primary>value object</primary></indexterm>
A common use case for an application running in a servlet or
application server is to "detach" objects from all server resources,
modify them, and then "attach" them again. For example, a servlet
might store persistent data in a user session between a modification
based on a series of web forms. Between each form request, the web
container might decide to serialize the session, requiring that the
stored persistent state be disassociated from any other
resources. Similarly, a client/server application might
transfer persistent objects to a client via serialization, allow the
client to modify their state, and then have the client return the
modified data in order to be saved. This is sometimes referred to as
the <emphasis>data transfer object</emphasis> or <emphasis>value
object</emphasis> pattern, and it allows fine-grained manipulation
of data objects without incurring the overhead of multiple remote
method invocations.
</para>
<para>
EJB persistence provides support for this pattern by automatically
detaching entities when they are serialized or when a persistence
context ends (see
<xref linkend="jpa_overview_emfactory_perscontext"/> for an
exploration of persistence contexts). The EJB persistence
<emphasis>merge</emphasis> API re-attaches detached entities.
This allows you to detach a persistent instance, modify the
detached instance offline, and merge the instance back into an
<classname>EntityManager</classname> (either the same one that
detached the instance, or a new one). The changes will then be
applied to the existing instance from the datastore.
</para>
<para>
A detached entity maintains its persistent identity, but cannot load
additional state from the datastore. Accessing any persistent field or
property that was not loaded at the time of detachment has undefined
results. Also, be sure not to alter the version or identity fields of
detached instances if you plan on merging them later.
</para>
<para>
The <methodname>merge</methodname> method returns a managed copy of the
given detached entity. Changes made to the persistent state of the
detached entity are applied to this managed instance. Because merging
involves changing persistent state, you can only merge within a
transaction.
</para>
<para>
If you attempt to merge an instance whose representation has
changed in the datastore since detachment, the merge operation will
throw an exception, or the transaction in which you perform the
merge will fail on commit, just as if a normal optimistic conflict
were detected.
</para>
<note>
<para>
OpenJPA offers enhancements to EJB persistence detachment
functionality, including additional options to control which
fields are detached. See <xref linkend="ref_guide_detach"/>
in the Reference Guide for details.
</para>
</note>
<para>
For a given entity <literal>A</literal>, the <methodname>merge
</methodname> method behaves as follows:
</para>
<itemizedlist>
<listitem>
<para>
If <literal>A</literal> is a detached entity, its state
is copied into existing managed instance <literal>A'</literal>
of the same entity identity, or a new managed copy of
<literal>A</literal> is created.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is a new entity, a new managed
entity <literal>A'</literal> is created and the state of
<literal>A</literal> is copied into <literal>A'</literal>.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is an existing managed entity, it is
ignored. However, the merge operation still cascades as
defined below.
</para>
</listitem>
<listitem>
<para>
If <literal>A</literal> is a removed entity, an
<classname>IllegalArgumentException</classname> is thrown.
</para>
</listitem>
<listitem>
<para>
The merge operation recurses on all relation fields of
<literal>A</literal> whose
<link linkend="jpa_overview_meta_cascade">cascades</link>
include <literal>CascadeType.MERGE</literal>.
</para>
</listitem>
</itemizedlist>
<programlisting format="linespecific">
public void lock (Object entity, LockModeType mode);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>lock</secondary></indexterm><indexterm><primary>locking</primary><seealso>EntityManager</seealso></indexterm>
This method locks the given entity using the named mode. The
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/LockmodeType.html"><classname>javax.persistence.LockModeType</classname></ulink> enum
defines two modes:
</para>
<itemizedlist>
<listitem>
<para><literal>READ</literal>: Other transactions may concurrently
read the object, but cannot concurrently update it.
</para>
</listitem>
<listitem>
<para><literal>WRITE</literal>: Other transactions cannot
concurrently read or write the object. When a transaction
is committed that holds WRITE locks on any entites, those
entites will have their version incremented even if
the entities themselves did not change in the transaction.
</para>
</listitem>
</itemizedlist>
<note>
<para>
OpenJPA has additional APIs for controlling object locking. See
<xref linkend="ref_guide_locking"/> in the Reference Guide for
details.
</para>
</note>
<para>
The following diagram illustrates the lifecycle of an entity with
respect to the APIs presented in this section.
</para>
<mediaobject>
<imageobject>
<!-- PNG image data, 445 x 337 (see README) -->
<imagedata fileref="img/jpa-state-transitions.png" width="297px"/>
</imageobject>
</mediaobject>
</section>
<section id="jpa_overview_em_lifeexamples">
<title>Lifecycle Examples</title>
<para>
The examples below demonstrate how to use the lifecycle methods
presented in the previous section. The examples are appropriate for
out-of-container use. Within a container, <classname>
EntityManager</classname>s are usually injected, and transactions are
usually managed. You would therefore omit the
<methodname>createEntityManager</methodname> and <methodname>close
</methodname> calls, as well as all transaction demarcation code.
</para>
<example id="jpa_overview_em_lifecycle_persist">
<title>Persisting Objects</title>
<indexterm>
<primary>persistent objects</primary>
<secondary>persisting</secondary>
<tertiary>example</tertiary>
</indexterm>
<programlisting format="linespecific">
// create some objects
Magazine mag = new Magazine ("1B78-YU9L", "JavaWorld");
Company pub = new Company ("Weston House");
pub.setRevenue (1750000D);
mag.setPublisher (pub);
pub.addMagazine (mag);
Article art = new Article ("EJB Rules!", "Transparent Object Persistence");
art.addAuthor (new Author ("Fred", "Hoyle"));
mag.addArticle (art);
// persist
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
em.persist (mag);
em.persist (pub);
em.persist (art);
em.getTransaction ().commit ();
// or we could continue using the EntityManager...
em.close ();
</programlisting>
</example>
<example id="jpa_overview_em_lifecycle_update">
<title>Updating Objects</title>
<indexterm>
<primary>persistent objects</primary>
<secondary>updating</secondary>
<tertiary>example</tertiary>
</indexterm>
<programlisting format="linespecific">
Magazine.MagazineId mi = new Magazine.MagazineId ();
mi.isbn = "1B78-YU9L";
mi.title = "JavaWorld";
// updates should always be made within transactions; note that
// there is no code explicitly linking the magazine or company
// with the transaction; EJB automatically tracks all changes
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
Magazine mag = em.find (Magazine.class, mi);
mag.setPrice (5.99);
Company pub = mag.getPublisher ();
pub.setRevenue (1750000D);
em.getTransaction ().commit ();
// or we could continue using the EntityManager...
em.close ();
</programlisting>
</example>
<example id="jpa_overview_em_lifecycle_delete">
<title>Removing Objects</title>
<indexterm>
<primary>persistent objects</primary>
<secondary>deleting</secondary>
<tertiary>example</tertiary>
</indexterm>
<programlisting format="linespecific">
// assume we have an object id for the company whose subscriptions
// we want to delete
Object oid = ...;
// deletes should always be made within transactions
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
Company pub = (Company) em.find (Company.class, oid);
for (Subscription sub : pub.getSubscriptions ())
em.remove (sub);
pub.getSubscriptions ().clear ();
em.getTransaction ().commit ();
// or we could continue using the EntityManager...
em.close ();
</programlisting>
</example>
<example id="jpa_overview_em_detachex">
<title>Detaching and Merging</title>
<para>
This example demonstrates a common client/server scenario. The
client requests objects and makes changes to them, while the
server handles the object lookups and transactions.
</para>
<programlisting format="linespecific">
// CLIENT:
// requests an object with a given oid
Record detached = (Record) getFromServer (oid);
...
// SERVER:
// send object to client; object detaches on EM close
Object oid = processClientRequest ();
EntityManager em = emf.createEntityManager ();
Record record = em.find (Record.class, oid);
em.close ();
sendToClient (record);
...
// CLIENT:
// makes some modifications and sends back to server
detached.setSomeField ("bar");
sendToServer (detached);
...
// SERVER:
// merges the instance and commit the changes
Record modified = (Record) processClientRequest ();
EntityManager em = emf.createEntityManager ();
em.getTransaction ().begin ();
Record merged = (Record) em.merge (modified);
merged.setLastModified (System.currentTimeMillis ());
merged.setModifier (getClientIdentityCode ());
em.getTransaction ().commit ();
em.close ();
</programlisting>
</example>
</section>
<section id="jpa_overview_em_identity">
<title>Entity Identity Management</title>
<para>
Each <classname>EntityManager</classname> is responsible for
managing the persistent identities of the managed objects in the
persistence context. The following methods allow you to interact
with the management of persistent identities. The behavior of these
methods is deeply affected by the persistence context type of the
<classname>EntityManager</classname>; see
<xref linkend="jpa_overview_emfactory_perscontext"/> for an
explanation of persistence contexts.
</para>
<programlisting format="linespecific">
public &lt;T&gt; T find (Class&lt;T&gt; cls, Object oid);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>find</secondary><seealso>identity</seealso></indexterm><indexterm><primary>find</primary><seealso>EntityManager</seealso></indexterm><indexterm><primary>identity</primary><secondary>retrieving objects by identity</secondary></indexterm>
This method returns the persistent instance of the given type with
the given persistent identity. If the instance is already present in
the current persistence context, the cached version will be returned.
Otherwise, a new instance will be constructed and loaded with
state from the datastore. If no entity with the given type and identity
exists in the datastore, this method returns null.
</para>
<programlisting format="linespecific">
public &lt;T&gt; T getReference (Class&lt;T&gt; cls, Object oid);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>getReference</secondary><seealso>identity</seealso></indexterm><indexterm><primary>getReference</primary><seealso>EntityManager</seealso></indexterm><indexterm><primary>identity</primary><secondary>retrieving objects by identity</secondary></indexterm><indexterm><primary>EntityNotFoundException</primary></indexterm>
This method is similar to <methodname>find</methodname>, but does not
necessarily go to the database when the entity is not found in cache.
The implementation may construct a <emphasis>hollow</emphasis> entity
and return it to you instead. Hollow entities do not have any
state loaded. The state only gets loaded when you attempt to access
a persistent field. At that time, the implementation may throw an
<classname>EntityNotFoundException</classname> if it discovers that
the entity does not exist in the datastore. The implementation may
also throw an <classname>EntityNotFoundException</classname> from
the <methodname>getReference</methodname> method itself. Unlike
<methodname>find</methodname>, <methodname>getReference</methodname>
does not return null.
</para>
<programlisting format="linespecific">
public boolean contains (Object entity);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>contains</secondary></indexterm><indexterm><primary>contains</primary><seealso>EntityManager</seealso></indexterm>
Returns true if the given entity is part of the current persistence
context, and false otherwise. Removed entities are not considered part
of the current persistence context.
</para>
</section>
<section id="jpa_overview_em_cache">
<title>Cache Management</title>
<indexterm zone="jpa_overview_em_cache">
<primary>EntityManager</primary>
<secondary>cache</secondary>
</indexterm>
<programlisting format="linespecific">
public void flush ();
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>flush</secondary></indexterm><indexterm><primary>flush</primary><seealso>EntityManager</seealso></indexterm><indexterm><primary>transactions</primary><secondary>flushing changes before commit</secondary></indexterm>
The <methodname>flush</methodname> method writes any changes that have
been made in the current transaction to the datastore. If the
<classname>EntityManager</classname> does not already have a
connection to the datastore, it obtains one for the flush and retains
it for the duration of the transaction. Any exceptions during flush
cause the transaction to be marked for rollback.
See <xref linkend="jpa_overview_trans"/>.
</para>
<para>
Flushing requires an active transaction. If there isn't a transaction
in progress, the <methodname>flush</methodname> method throws a
<classname>TransactionRequiredException</classname>.
</para>
<programlisting format="linespecific">
public FlushModeType getFlushMode ();
public void setFlushMode (FlushModeType flushMode);
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>FlushMode</secondary></indexterm><indexterm><primary>FlushMode</primary></indexterm>
The <classname>EntityManager</classname>'s <literal>FlushMode</literal>
property controls whether to flush transactional changes before
executing queries. This allows the query results to take into account
changes you have made during the current transaction. Available
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/FlushModeType.html"><classname>javax.persistence.FlushModeType</classname></ulink> constants
are:
</para>
<itemizedlist>
<listitem>
<para><literal>COMMIT</literal>: Only flush when committing, or
when told to do so through the <methodname>flush</methodname>
method. Query results may not take into account changes made
in the current transaction.
</para>
</listitem>
<listitem>
<para><literal>AUTO</literal>: The implementation is permitted to
flush before queries to ensure that the results reflect the
most recent object state.
</para>
</listitem>
</itemizedlist>
<para>
You can also set the flush mode on individual
<link linkend="jpa_overview_query"><classname>Query</classname></link>
instances.
</para>
<note>
<para>
OpenJPA only flushes before a query if the query might be affected
by data changed in the current transaction. Additionally,
OpenJPA allows fine-grained control over flushing behavior.
See the Reference Guide's
<xref linkend="ref_guide_dbsetup_retain"/>.
</para>
</note>
<programlisting format="linespecific">
public void clear ();
</programlisting>
<para><indexterm><primary>EntityManager</primary><secondary>clear</secondary></indexterm><indexterm><primary>clear</primary><seealso>EntityManager</seealso></indexterm>
Clearing the <classname>EntityManager</classname> effectively ends the
persistence context. All entities managed by
the <classname>EntityManager</classname> become detached.
</para>
</section>
<section id="jpa_overview_em_query">
<title>Query Factory</title>
<indexterm zone="jpa_overview_em_query">
<primary>EntityManager</primary>
<secondary>as Query factory</secondary>
<seealso>Query</seealso>
</indexterm>
<indexterm zone="jpa_overview_em_query">
<primary>Query</primary>
<secondary>creating</secondary>
</indexterm>
<programlisting format="linespecific">
public Query createQuery (String query);
</programlisting>
<para><classname>Query</classname> objects are used to find entities
matching certain criteria. The <methodname>createQuery</methodname>
method creates a query using the given EJB Query Language (JPQL)
string. See <xref linkend="jpa_overview_query"/> for details.
</para>
<programlisting format="linespecific">
public Query createNamedQuery (String name);
</programlisting>
<para>
This method retrieves a query defined in metadata by name. The returned
<classname>Query</classname> instance is initialized with the
information declared in metadata. For more information on named
queries, read <xref linkend="jpa_overview_query_named"/>.
</para>
<programlisting format="linespecific">
public Query createNativeQuery (String sql);
public Query createNativeQuery (String sql, Class resultCls);
public Query createNativeQuery (String sql, String resultMapping);
</programlisting>
<para><emphasis>Native</emphasis> queries are queries in the datastore's
native language. For relational databases, this the Structured Query
Language (SQL). <xref linkend="jpa_overview_sqlquery"/> elaborates
on EJB persistence's native query support.
</para>
</section>
<section id="jpa_overview_em_closing">
<title>Closing</title>
<indexterm zone="jpa_overview_em_closing">
<primary>EntityManager</primary>
<secondary>closing</secondary>
</indexterm>
<programlisting format="linespecific">
public boolean isOpen ();
public void close ();
</programlisting>
<para>
When an <classname>EntityManager</classname> is no longer
needed, you should call its <methodname>close</methodname> method.
Closing an <classname>EntityManager</classname> releases any resources
it is using. The persistence context ends, and the entities managed by
the <classname>EntityManager</classname> become detached.
Any <classname>Query</classname> instances the <classname>EntityManager
</classname> created become invalid.
Calling any method other than <methodname>isOpen</methodname> on a
closed <classname>EntityManager</classname> results in an
<classname>IllegalStateException</classname>. You cannot close a
<classname>EntityManager</classname> that is in the middle of a
transaction.
</para>
<para>
If you are in a managed environment using injected entity managers,
you should not close them.
</para>
</section>
</chapter>

View File

@ -0,0 +1,365 @@
<chapter id="jpa_overview_emfactory">
<title>EntityManagerFactory</title>
<indexterm zone="jpa_overview_emfactory">
<primary>EntityManagerFactory</primary>
</indexterm>
<mediaobject>
<imageobject>
<!-- PNG image data, 418 x 274 (see README) -->
<imagedata fileref="img/entitymanagerfactory.png" width="279px"/>
</imageobject>
</mediaobject>
<para>
The <classname>EntityManagerFactory</classname> creates
<classname>EntityManager</classname> instances for application
use.
</para>
<note>
<para>
OpenJPA extends the standard <classname>EntityManagerFactory</classname>
interface with the
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManagerFactory.html"><classname>OpenJPAEntityManagerFactory</classname></ulink> to provide
additional functionality.
</para>
</note>
<section id="jpa_overview_emfactory_obtain">
<title>Obtaining an EntityManagerFactory</title>
<indexterm zone="jpa_overview_emfactory_obtain">
<primary>EntityManagerFactory</primary>
<secondary>construction</secondary>
</indexterm>
<indexterm>
<primary>Java Connector Architecture</primary>
<see>JCA</see>
</indexterm>
<indexterm>
<primary>JCA</primary>
</indexterm>
<para>
Within a container, you will typically use <emphasis>injection
</emphasis> to access an <classname>EntityManagerFactory</classname>.
There are, however, alternative mechanisms for
<classname>EntityManagerFactory</classname> construction.
</para>
<para>
Some vendors may supply public constructors for their
<classname>EntityManagerFactory</classname> implementations, but
we recommend using the Java Connector Architecture (JCA) in a managed
environment, or the <classname>Persistence</classname> class'
<methodname>createEntityManagerFactory</methodname> methods in an
unmanaged environment, as described in
<xref linkend="jpa_overview_persistence"/>. These strategies allow
vendors to pool factories, cutting down on resource utilization.
</para>
<para><indexterm><primary>JNDI</primary></indexterm>
JPA allows you to create and configure an
<classname>EntityManagerFactory</classname>, then store it in a
Java Naming and Directory Interface (JNDI) tree for later retrieval
and use.
</para>
</section>
<section id="jpa_overview_emfactory_em">
<title>Obtaining EntityManagers</title>
<indexterm zone="jpa_overview_emfactory_em">
<primary>EntityManager</primary>
<secondary>obtaining</secondary>
<seealso>EntityManagerFactory</seealso>
</indexterm>
<indexterm zone="jpa_overview_emfactory_em">
<primary>EntityManagerFactory</primary>
<secondary>obtaining EntityManagers</secondary>
</indexterm>
<programlisting format="linespecific">
public EntityManager createEntityManager ();
public EntityManager createEntityManager (Map map);
</programlisting>
<para>
The two <methodname>createEntityManager</methodname> methods above
create a new <classname>EntityManager</classname> each time they are
invoked. The optional <classname>Map</classname> is used to to supply
vendor-specific settings. If you have configured your implementation
for JTA transactions and a JTA transaction is active, the returned
<classname>EntityManager</classname> will be synchronized with that
transaction.
<!--
<classname>EntityManager</classname> with a persistence context type of
<literal>TRANSACTION</literal>. The second version allows you to
specify the persistence context type. We relate the differences
between persistence context types
<link linkend="jpa_overview_emfactory_perscontext">below</link>.
-->
</para>
<note>
<para>
OpenJPA recognizes the following string keys in the map supplied to
<methodname>createEntityManager</methodname>:
</para>
<itemizedlist>
<listitem>
<para>
<literal>openjpa.ConnectionUserName</literal>
</para>
</listitem>
<listitem>
<para>
<literal>openjpa.ConnectionPassword</literal>
</para>
</listitem>
<listitem>
<para>
<literal>openjpa.ConnectionRetainMode</literal>
</para>
</listitem>
<listitem>
<para>
<literal>openjpa.TransactionMode</literal>
</para>
</listitem>
<listitem>
<para><literal>openjpa.&lt;property&gt;</literal>, where
<emphasis>&lt;property&gt;</emphasis> is any JavaBean
property of the
<ulink url="../apidocs/org/apache/openjpa/persistence/OpenJPAEntityManager.html"><classname>
org.apache.openjpa.persistence.OpenJPAEntityManager</classname></ulink>.
</para>
</listitem>
</itemizedlist>
<para>
The last option uses reflection to configure any property of OpenJPA's
<classname>EntityManager</classname> implementation with the value
supplied in your map. The first options correspond exactly to
the same-named OpenJPA configuration keys described in
<xref linkend="ref_guide_conf"/> of the Reference Guide.
</para>
</note>
</section>
<section id="jpa_overview_emfactory_perscontext">
<title>Persistence Context</title>
<indexterm zone="jpa_overview_emfactory_perscontext">
<primary>persistence context</primary>
</indexterm>
<indexterm>
<primary>PersistenceContextType</primary>
<see>persistence context</see>
</indexterm>
<para>
A persistence context is a set of entities such that for any persistent
identity there is a unique entity instance. Within a persistence
context, entities are <emphasis>managed</emphasis>. The <classname>
EntityManager</classname> controls their lifecycle, and they can access
datastore resources.
</para>
<para>
When a persistence context ends, previously-managed entities become
<emphasis>detached</emphasis>. A detached entity is no longer under
the control of the <classname>EntityManager</classname>, and no longer
has access to datastore resources. We discuss detachment is detail in
<xref linkend="jpa_overview_em_lifecycle"/>. For now, it is sufficient
to know that detachment as has two obvious consequences:
</para>
<orderedlist>
<listitem>
<para>
The detached entity cannot load any additional persistent
state.
</para>
</listitem>
<listitem>
<para>
The <classname>EntityManager</classname> will not return the
detached entity from <methodname>find</methodname>, nor will
queries include the detached entity in their results. Instead,
<methodname>find</methodname> method invocations and query
executions that would normally incorporate the detached entity
will create a new managed entity with the same identity.
</para>
</listitem>
</orderedlist>
<note>
<para>
OpenJPA offers several features related to detaching entities. See
<xref linkend="ref_guide_detach"/> in the Reference Guide.
<xref linkend="ref_guide_detach_graph"/> in particular describes
how to use the <literal>DetachState</literal> setting to boost
the performance of merging detached entities.
</para>
</note>
<para>
Injected <classname>EntityManager</classname>s have use a
<emphasis>transaction</emphasis>, while <classname>
EntityManager</classname>s obtained through the
<classname>EntityManagerFactory</classname> have an <emphasis>
extended</emphasis> persistence context. We describe these persistence
context types below.
</para>
<section id="jpa_overview_emfactory_perscontext_trans">
<title>Transaction Persistence Context</title>
<para>
Under the transaction persistence context model, an <classname>
EntityManager</classname> begins a new persistence context
with each transaction, and ends the context when the transaction
commits or rolls back. Within the transaction, entities you
retrieve through the <classname>EntityManager</classname> or via
<classname>Queries</classname> are managed entities. They
can access datastore resources to lazy-load additional
persistent state as needed, and only one entity may exist for any
persistent identity.
</para>
<para>
When the transaction completes, all entities lose their
association with the <classname>EntityManager</classname> and
become detached. Traversing a persistent field that wasn't
already loaded now has undefined results. And using the <classname>
EntityManager</classname> or a <classname>Query</classname> to
retrieve additional objects may now create new instances with the
same persistent identities as detached instances.
</para>
<para>
If you use an <classname>EntityManager</classname> with a
transaction persistence context model outside of
an active transaction, each method invocation creates a new
persistence context, performs the method action, and ends the
persistence context. For example, consider using the
<methodname>EntityManager.find</methodname> method outside
of a transaction. The <classname>EntityManager</classname> will
create a temporary persistence context, perform the find operation,
end the persistence context, and return the detached result object
to you. A second call with the same id will return a second
detached object.
</para>
<para>
When the next transaction begins, the <classname>EntityManager
</classname> will begin a new persistence context, and will again
start returning managed entities. As you'll see in
<xref linkend="jpa_overview_em"/>, you can also merge the
previously-detached entites back into the new persistence context.
</para>
<example id="jpa_overview_emfactory_perscontext_transex">
<title>Behavior of Transaction Persistence Context</title>
<para>
The following code illustrates the behavior of entites under
an <classname>EntityManager</classname> using a transaction
persistence context.
</para>
<programlisting format="linespecific">
EntityManager em; // injected
...
// outside a transaction:
// each operation occurs in a separate persistence context, and returns
// a new detached instance
Magazine mag1 = em.find (Magazine.class, magId);
Magazine mag2 = em.find (Magazine.class, magId);
assertTrue (mag2 != mag1);
...
// transaction begins:
// within a transaction, a subsequent lookup doesn't return any of the
// detached objects. however, two lookups within the same transaction
// return the same instance, because the persistence context spans the
// transaction
Magazine mag3 = em.find (Magazine.class, magId);
assertTrue (mag3 != mag1 &amp;&amp; mag3 != mag2);
Magazine mag4 = em.find (Magazine.class (magId);
assertTrue (mag4 == mag3);
...
// transaction commits:
// once again, each operation returns a new instance
Magazine mag5 = em.find (Magazine.class, magId);
assertTrue (mag5 != mag3);
</programlisting>
</example>
</section>
<section id="jpa_overview_emfactory_perscontext_extend">
<title>Extended Persistence Context</title>
<para>
An <classname>EntityManager</classname> using an extended
persistence context maintains the same persistence context for
its entire lifecycle. Whether inside a transaction or not, all
entities returned from the <classname>EntityManager</classname>
are managed, and the <classname>EntityManager</classname> never
creates two entity instances to represent the same persistent
identity. Entities only become detached when you finally close
the <classname>EntityManager</classname> (or when they are
serialized).
</para>
<example id="jpa_overview_emfactory_perscontext_extendex">
<title>Behavior of Extended Persistence Context</title>
<para>
The following code illustrates the behavior of entites under
an <classname>EntityManager</classname> using an extended
persistence context.
</para>
<programlisting format="linespecific">
EntityManagerFactory emf = ...
EntityManager em = emf.createEntityManager (PersistenceContextType.EXTENDED);
// persistence context active for entire life of EM, so only one entity
// for a given persistent identity
Magazine mag1 = em.find (Magazine.class, magId);
Magazine mag2 = em.find (Magazine.class, magId);
assertTrue (mag2 == mag1);
em.getTransaction ().begin ();
// same persistence context active within the transaction
Magazine mag3 = em.find (Magazine.class, magId);
assertTrue (mag3 == mag1);
Magazine mag4 = em.find (Magazine.class (magId);
assertTrue (mag4 == mag1);
em.getTransaction.commit ();
// when the transaction commits, instance still managed
Magazine mag5 = em.find (Magazine.class, magId);
assertTrue (mag5 == mag1);
// instance finally becomes detached when EM closes
em.close ();
</programlisting>
</example>
</section>
</section>
<section id="jpa_overview_emfactory_close">
<title>Closing the EntityManagerFactory</title>
<indexterm zone="jpa_overview_emfactory_close">
<primary>EntityManagerFactory</primary>
<secondary>closing</secondary>
</indexterm>
<programlisting format="linespecific">
public boolean isOpen ();
public void close ();
</programlisting>
<para><classname>EntityManagerFactory</classname> instances are
heavyweight objects. Each factory might maintain a metadata cache,
object state cache, <classname>EntityManager</classname> pool,
connection pool, and more. If your application no longer needs an
<classname>EntityManagerFactory</classname>, you should close it
to free these resources. When an <classname>EntityManagerFactory
</classname> closes, all <classname>EntityManager</classname>s
from that factory, and by extension all entities managed
by those <classname>EntityManager</classname>s, become invalid.
Attempting to close an <classname>EntityManagerFactory</classname>
while one or more of its <classname>EntityManager</classname>s
has an active transaction may result in an
<classname>IllegalStateException</classname>.
</para>
<para>
Closing an <classname>EntityManagerFactory</classname> should not
be taken lightly. It is much better to keep a factory open for a long
period of time than to repeatedly create and close new factories. Thus,
most applications will never close the factory, or only close it when
the application is exiting. Only applications that require multiple
factories with different configurations have an obvious reason to
create and close multiple <classname>EntityManagerFactory
</classname> instances. Once a factory is closed, all methods except
<methodname>isOpen</methodname> throw an <classname>
IllegalStateException</classname>.
</para>
</section>
</chapter>

View File

@ -0,0 +1,57 @@
<chapter id="jpa_overview_intro">
<title>Introduction</title>
<para><indexterm><primary>EJB3 Persistence</primary><see>EJB</see></indexterm><indexterm><primary>EJB</primary></indexterm>
Enterprise Java Beans 3.0 Persistence (EJB persistence) is a specification
from Sun Microsystems for the persistence of Java objects to any relational
datastore. EJB persistence requires J2SE 1.5 (also referred to as "Java 5")
or higher, as it makes heavy use of new Java language features such as
annotations and generics. This document provides an overview of EJB
persistence. Unless otherwise noted, the information presented
applies to all EJB persistence implementations.
</para>
<note>
<para>
This document describes the Public Draft of the EJB 3.0
persistence specification.
</para>
<para>
For coverage of OpenJPA's many extensions to the EJB persistence
specification, see the <link linkend="ref_guide_intro">Reference
Guide</link>.
</para>
</note>
<section id="jpa_overview_intro_audience">
<title>Intended Audience</title>
<para>
This document is intended for developers who want to learn about
EJB persistence in order to use it in their applications.
It assumes that you have a strong knowledge of object-oriented concepts
and Java, including Java 5 annotations and generics. It also assumes
some experience with relational databases and the
Structured Query Language (SQL).
</para>
</section>
<section id="jpa_overview_intro_transpers">
<title>Lightweight Persistence</title>
<indexterm zone="jpa_overview_intro_transpers">
<primary>lightweight persistence</primary>
</indexterm>
<para><indexterm><primary>persistent data</primary></indexterm><emphasis>Persistent data</emphasis> is information that can
outlive the program that creates it. The majority of complex
programs use persistent data: GUI applications need to store user
preferences across program invocations, web applications track
user movements and orders over long periods of time, etc.
</para>
<para><emphasis>Lightweight persistence</emphasis> is the storage and
retrieval of persistent data with little or no work from you, the
developer. For example, Java serialization<indexterm><primary>serialization</primary></indexterm> is a form of
lightweight persistence because it can be used to persist Java
objects directly to a file with very little effort. Serialization's
capabilities as a lightweight persistence mechanism pale in
comparison to those provided by EJB, however. The next
chapter compares EJB to serialization and other available
persistence mechanisms.
</para>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,219 @@
<chapter id="jpa_overview_persistence">
<title>Persistence</title>
<indexterm zone="jpa_overview_persistence">
<primary>Persistence</primary>
</indexterm>
<indexterm zone="jpa_overview_persistence">
<primary>EntityManagerFactory</primary>
<secondary>construction</secondary>
</indexterm>
<indexterm zone="jpa_overview_persistence">
<primary>Persistence</primary>
<secondary>getEntityManagerFactory</secondary>
</indexterm>
<indexterm zone="jpa_overview_persistence">
<primary>getEntityManagerFactory</primary>
<seealso>Persistence</seealso>
</indexterm>
<mediaobject>
<imageobject>
<!-- PNG image data, 427 x 121 (see README) -->
<imagedata fileref="img/persistence.png" width="285px"/>
</imageobject>
</mediaobject>
<note>
<para>
OpenJPA also includes the
<ulink url="../../api/openjpa/persistence/OpenJPAPersistence.html"><classname>OpenJPAPersistence</classname></ulink> helper class to provide
additional utility methods.
</para>
</note>
<para>
Within a container, you will typically use <emphasis>injection
</emphasis> to access an <classname>EntityManagerFactory</classname>.
Applications operating of a container, however, can use the
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/Persistence.html"><classname>Persistence</classname></ulink> class to obtain
<classname>EntityManagerFactory</classname> objects in a vendor-neutral
fashion.
</para>
<programlisting format="linespecific">
public static EntityManagerFactory createEntityManagerFactory (String name);
public static EntityManagerFactory createEntityManagerFactory (String name, Map props);
</programlisting>
<para>
Each <methodname>createEntityManagerFactory</methodname> method searches
the system for an <classname>EntityManagerFactory</classname> definition
with the given name. Use <literal>null</literal> for an unnamed factory.
The optional map contains vendor-specific property settings used to further
configure the factory.
</para>
<para><filename>persistence.xml</filename> files define <classname>
EntityManagerFactories</classname>. The <methodname>
createEntityManagerFactory</methodname> methods search for <filename>
persistence.xml</filename> files within the <filename>META-INF</filename>
directory of any <literal>CLASSPATH</literal> element. For example, if
your <literal>CLASSPATH</literal> contains the <filename>conf</filename>
directory, you could place an <classname>EntityManagerFactory</classname>
definition in <filename>conf/META-INF/persistence.xml</filename>.
</para>
<section id="jpa_overview_persistence_xml">
<title>persistence.xml</title>
<para>
The <filename>persistence.xml</filename> file format obeys the following
Document Type Descriptor (DTD):
</para>
<programlisting format="linespecific">
&lt;!ELEMENT persistence (persistence-unit*)&gt;
&lt;!ELEMENT persistence-unit (description?,provider?,jta-datasource?,
non-jta-datasource?,(class|jar-file|mapping-file)*,
exclude-unlisted-classes?,properties?)&gt;
&lt;!ATTLIST persistence-unit name CDATA #REQUIRED&gt;
&lt;!ATTLIST persistence-unit transaction-type (JTA|RESOURCE_LOCAL) "JTA"&gt;
&lt;!ELEMENT description (#PCDATA)&gt;
&lt;!ELEMENT provider (#PCDATA)&gt;
&lt;!ELEMENT jta-datasource (#PCDATA)&gt;
&lt;!ELEMENT non-jta-datasource (#PCDATA)&gt;
&lt;!ELEMENT mapping-file (#PCDATA)&gt;
&lt;!ELEMENT jar-file (#PCDATA)&gt;
&lt;!ELEMENT class (#PCDATA)&gt;
&lt;!ELEMENT exclude-unlisted-classes EMPTY&gt;
&lt;!ELEMENT properties (property*)&gt;
&lt;!ELEMENT property EMPTY&gt;
&lt;!ATTLIST property name CDATA #REQUIRED&gt;
&lt;!ATTLIST property value CDATA #REQUIRED&gt;
</programlisting>
<para>
The root element of a <filename>persistence.xml</filename> file is
<literal>persistence</literal>, which then contains one or more
<literal>persistence-unit</literal> definitions.
Each persistence unit describes the configuration for the entity
managers created by the persistence unit's entity manager factory.
The persistence unit can specify these elements and attribtues.
</para>
<itemizedlist>
<listitem>
<para><literal>name</literal>: This is the name you pass to the
<methodname>Persistence.createEntityManagerFactory</methodname>
methods described above. The name attribute is required.
</para>
</listitem>
<listitem>
<para><literal>transaction-type</literal>: Whether to use managed
(<literal>JTA</literal>) or local
(<literal>RESOURCE_LOCAL</literal>) transaction management.
Defaults to <literal>JTA</literal>.
</para>
</listitem>
<listitem>
<para><literal>provider</literal>: If you are using a third-party
JPA vendor, this element names its implementation of the
<ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/spi/PersistenceProvider.html"><classname>PersistenceProvider</classname></ulink> bootstrapping
interface.
</para>
<note>
<para>
Set the <literal>provider</literal> to <classname>
org.apache.openjpa.persistence.PersistenceProviderImpl</classname>
to use OpenJPA.
</para>
</note>
</listitem>
<listitem>
<para><literal>jta-data-source</literal>: The JNDI name of a JDBC
<classname>DataSource</classname> that is automatically enlisted
in JTA transactions. This may be an XA <classname>
DataSource</classname>.
</para>
</listitem>
<listitem>
<para><literal>non-jta-data-source</literal>: The JNDI name of a JDBC
<classname>DataSource</classname> that is not enlisted
in JTA transactions.
</para>
</listitem>
<listitem>
<para><literal>mapping-file</literal>*: The resource names of
XML mapping files for entities and embeddable classes.
You can also specify mapping information in an <filename>
orm.xml</filename> file in your <filename>META-INF</filename>
directory. If present, the <filename>orm.xml</filename>
mapping file will be read automatically.
</para>
</listitem>
<listitem>
<para><literal>jar-file</literal>*: The names of jar files containing
entities and embeddable classes. The implementation will scan
the jar for annotated classes.
</para>
</listitem>
<listitem>
<para><literal>class</literal>*: The class names of entities and
embeddable classes.
</para>
</listitem>
<listitem>
<para><literal>properties</literal>: This element contains nested
<literal>property</literal> elements used to specify
vendor-specific settings. Each <literal>property</literal>
has a name attribute and a value attribute.
</para>
<note>
<para>
The Reference Guide's <xref linkend="ref_guide_conf"/>
describes OpenJPA's configuration properties.
</para>
</note>
</listitem>
</itemizedlist>
<para>
Here is a typical <filename>persistence.xml</filename> file for a
non-EE environment:
</para>
<example id="jpa_overview_persistence_xmlex">
<title>persistence.xml</title>
<programlisting format="linespecific">
&lt;?xml version="1.0"?&gt;
&lt;persistence&gt;
&lt;persistence-unit name="openjpa"&gt;
&lt;provider&gt;org.apache.openjpa.persistence.PersistenceProviderImpl&lt;/provider&gt;
&lt;class&gt;tutorial.Animal&lt;/class&gt;
&lt;class&gt;tutorial.Dog&lt;/class&gt;
&lt;class&gt;tutorial.Rabbit&lt;/class&gt;
&lt;class&gt;tutorial.Snake&lt;/class&gt;
&lt;properties&gt;
&lt;property name="openjpa.ConnectionURL" value="jdbc:hsqldb:tutorial_database"/&gt;
&lt;property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/&gt;
&lt;property name="openjpa.ConnectionUserName" value="sa"/&gt;
&lt;property name="openjpa.ConnectionPassword" value=""/&gt;
&lt;property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/&gt;
&lt;/properties&gt;
&lt;/persistence-unit&gt;
&lt;/persistence&gt;
</programlisting>
</example>
</section>
<section id="jpa_overview_persistence_use">
<title>Non-EE Use</title>
<para>
The example below demonstrates the <classname>Persistence</classname>
class in action. You will typically execute code like this on
application startup, then cache the resulting factory for future use.
This bootstrapping code is only necessary in non-EE environments; in
an EE environment <classname>EntityManagerFactories</classname> are
typically injected.
</para>
<example id="jpa_overview_persistence_getemfactory">
<title>Obtaining an EntityManagerFactory</title>
<programlisting format="linespecific">
// if your persistence.xml file does not contain all settings already, you
// can add vendor settings to a map
Properties props = new Properties ();
...
// create the factory defined by the "openjpa" entity-manager entry
EntityManagerFactory emf = Persistence.createEntityManagerFactory ("openjpa", props);
</programlisting>
</example>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,338 @@
<chapter id="jpa_overview_sqlquery">
<title>SQL Queries</title>
<indexterm zone="jpa_overview_sqlquery">
<primary>SQL queries</primary>
<seealso>Query</seealso>
</indexterm>
<indexterm>
<primary>Query</primary>
<secondary>SQL</secondary>
<see>SQL queries</see>
</indexterm>
<indexterm>
<primary>SQL</primary>
<secondary>queries</secondary>
<see>SQL queries</see>
</indexterm>
<indexterm>
<primary>Native</primary>
<secondary>queries</secondary>
<see>SQL queries</see>
</indexterm>
<para>
JPQL is a powerful query language, but there are times when it is
not enough. Maybe you're migrating a JDBC application to JPA
on a strict deadline, and you don't have time to translate your existing
SQL selects to JPQL. Or maybe a certain query requires
database-specific SQL your JPA implementation doesn't support.
Or maybe your DBA has spent hours crafting the perfect select statement
for a query in your application's critical path. Whatever the reason, SQL
queries can remain an essential part of an application.
</para>
<para>
You are probably familiar with executing SQL queries by obtaining a
<classname>java.sql.Connection</classname>, using the JDBC APIs to create
a <classname>Statement</classname>, and executing that <classname>Statement
</classname> to obtain a <classname>ResultSet</classname>. And of course,
you are free to continue using this low-level approach to SQL execution in
your JPA applications. However, JPA also supports executing SQL queries
through the <classname>javax.persistence.Query</classname>
interface introduced in <xref linkend="jpa_overview_query"/>.
Using a JPA SQL query, you can retrieve either persistent objects
or projections of column values. The following sections detail each use.
</para>
<section id="jpa_overview_sqlquery_create">
<title>Creating SQL Queries</title>
<indexterm zone="jpa_overview_sqlquery_create">
<primary>SQL queries</primary>
<secondary>creating</secondary>
</indexterm>
<para>
The <classname>EntityManager</classname> has two factory methods
suitable for creating SQL queries:
</para>
<programlisting format="linespecific">
public Query createNativeQuery (String sqlString, Class resultClass);
public Query createNativeQuery (String sqlString, String resultSetMapping);
</programlisting>
<para>
The first method is used to create a new <classname>Query</classname>
instance that will return instances of the specified class.
</para>
<para>
The second method uses a <literal>SqlResultSetMapping</literal>
to determine the type of object or objects to return.
The example below shows these methods in action.
</para>
<example id="jpa_overview_sqlquery_createex">
<title>Creating a SQL Query</title>
<programlisting format="linespecific">
EntityManager em = ...;
Query query = em.createNativeQuery ("SELECT * FROM MAG", Magazine.class);
processMagazines (query.getResultList ());
</programlisting>
</example>
<note>
<para><indexterm><primary>SQL queries</primary><secondary>stored procedures</secondary></indexterm><indexterm><primary>stored procedures</primary><secondary>as queries</secondary><seealso>Query</seealso></indexterm>
In addition to SELECT statements, OpenJPA supports stored procedure
invocations as SQL queries. OpenJPA will assume any SQL that does
not begin with the <literal>SELECT</literal> keyword (ignoring
case) is a stored procedure call, and invoke it as such at the
JDBC level.
</para>
</note>
</section>
<section id="jpa_overview_sqlquery_obj">
<title>Retrieving Persistent Objects with SQL</title>
<indexterm zone="jpa_overview_sqlquery_obj">
<primary>SQL queries</primary>
<secondary>retrieving persistent objects</secondary>
</indexterm>
<indexterm zone="jpa_overview_sqlquery_obj">
<primary>persistent objects</primary>
<secondary>retrieving with SQL</secondary>
<seealso>SQL queries</seealso>
</indexterm>
<para>
When you give a SQL <classname>Query</classname> a candidate class, it
will return persistent instances of that class. At a minimum, your
SQL must select the
class' primary key columns, discriminator column (if mapped), and
version column (also if mapped). The JPA runtime uses the values
of the primary key columns to construct each result object's identity,
and possibly to match it with a persistent object already in the
<classname>EntityManager</classname>'s cache. When an object is
not already cached, the
implementation creates a new object to represent the current result
row. It might use the discriminator column value to make sure it
constructs an object of the correct subclass. Finally, the query
records available version column data for use in optimistic concurrency
checking, should you later change the result object and flush it back
to the database.
</para>
<para>
Aside from the primary key, discriminator, and version columns, any
columns you select are used to populate the persistent fields of each
result object. JPA implementations will compete on how effectively
they map your selected data to your persistent instance fields.
</para>
<para>
Let's make the discussion above concrete with an example. It uses
the following simple mapping between a class and the database:
</para>
<mediaobject>
<imageobject>
<!-- PNG image data, 320 x 149 (see README) -->
<imagedata fileref="img/sqlquery-model.png" width="213px"/>
</imageobject>
</mediaobject>
<example id="jpa_overview_sqlquery_objex">
<title>Retrieving Persistent Objects</title>
<programlisting format="linespecific">
Query query = em.createNativeQuery ("SELECT ISBN, TITLE, PRICE, "
+ "VERS FROM MAG WHERE PRICE &gt; 5 AND PRICE &lt; 10", Magazine.class);
List&lt;Magazine&gt; results = query.getResultList ();
for (Magazine mag : results)
processMagazine (mag);
</programlisting>
</example>
<para>
The query above works as advertised, but isn't very flexible. Let's
update it to take in parameters for the minimum and maximum price,
so we can reuse it to find magazines in any price range:
</para>
<example id="jpa_overview_sqlquery_obj_paramex">
<title>SQL Query Parameters</title>
<programlisting format="linespecific">
Query query = em.createNativeQuery ("SELECT ISBN, TITLE, PRICE, "
+ "VERS FROM MAG WHERE PRICE &gt; ?1 AND PRICE &lt; ?2", Magazine.class);
query.setParameter (1, 5d);
query.setParameter (2, 10d);
List&lt;Magazine&gt; results = query.getResultList ();
for (Magazine mag : results)
processMagazine (mag);
</programlisting>
</example>
<para><indexterm><primary>SQL queries</primary><secondary>parameters</secondary></indexterm><indexterm><primary>parameters</primary><secondary>in SQL queries</secondary><seealso>SQL queries</seealso></indexterm>
Like JDBC prepared statements, SQL queries represent parameters with
question marks, but are followed by an integer to represent its
index.
</para>
</section>
<!--
<section id="jpa_overview_sqlquery_proj">
<title>SQL Projections</title>
<indexterm zone="jpa_overview_sqlquery_proj">
<primary>SQL queries</primary>
<secondary>projections</secondary>
</indexterm>
<indexterm zone="jpa_overview_sqlquery_proj">
<primary>projections</primary>
<secondary>of column data</secondary>
<seealso>SQL queries</seealso>
</indexterm>
<para>
SQL queries without a candidate class are treated as projections of
column data. If you select a single column, the query returns
a list of <classname>Object</classname>s. If you select multiple
columns, it returns a list of <classname>Object[]</classname>s.
In either case, each column value is obtained using the
<methodname>java.sql.ResultSet.getObject</methodname> method. The
following example demonstrates a query for the values of the
<literal>ISBN</literal> and <literal>VERS</literal> columns of all
<literal>MAG</literal> table records, using the data model we
defined in <xref linkend="jpa_overview_sqlquery_obj"/>.
</para>
<example id="jpa_overview_sqlquery_projex">
<title>Column Projection</title>
<programlisting>
Query query = em.newQuery ("javax.persistence.query.SQL",
"SELECT ISBN, VERS FROM MAG");
List results = query.getResultList ();
for (Iterator itr = results.iterator (); itr.hasNext ();)
{
Object[] data = (Object[]) results.next ();
processISBNAndVersion (data[0], data[1]);
}
</programlisting>
<para>
Notice that in the code above, we did not set a candidate class.
Therefore, the query is treated as a projection.
</para>
</example>
<para>
<indexterm>
<primary>SQL queries</primary>
<secondary>result class</secondary>
</indexterm>
Our discussion of JPQL query result classes in
<xref linkend="jpa_overview_query_resultcls"/> also
applies to SQL queries. As with JPQL queries, SQL queries can
automatically pack their results into objects of a specified type.
JPA uses the <methodname>java.sql.ResultSetMetaData.getColumnLabel
</methodname> method to match each column alias to the result class'
public fields and JavaBean setter methods. Here is a modification of
our example above that packs the selected column values into JavaBean
instances.
</para>
<example id="jpa_overview_sqlquery_proj_labelex">
<title>Result Class</title>
<programlisting>
public class Identity
{
private String id;
private int versionNumber;
public void setId (String id)
{
this.id = id;
}
public String getId ()
{
return id;
}
public void setVersionNumber (int versionNumber)
{
this.versionNumber = versionNumber;
}
public int getVersionNumber ()
{
return versionNumber;
}
}
Query query = em.createNativeQuery ("javax.persistence.query.SQL",
"SELECT ISBN AS id, VERS AS versionNumber FROM MAG", Identity.class);
List results = query.getResultList ();
for (Iterator itr = results.iterator (); itr.hasNext ();)
processIdentity ((Identity) itr.next ());
</programlisting>
</example>
</section>
<section id="jpa_overview_sqlquery_named">
<title>Named SQL Queries</title>
<indexterm zone="jpa_overview_sqlquery_named">
<primary>SQL queries</primary>
<secondary>named</secondary>
<see>named queries</see>
</indexterm>
<indexterm zone="jpa_overview_sqlquery_named">
<primary>named queries</primary>
<secondary>SQL</secondary>
</indexterm>
<para>
We discussed how to write named JPQL queries in
<xref linkend="jpa_overview_query_named"/>. Named queries, however,
are not limited to JPQL. By setting the <literal>query</literal>
element's <literal>language</literal> attribute to <literal>
javax.persistence.query.SQL</literal>, you can define a named SQL query. A
named SQL query within a <literal>class</literal> element queries for
instances of that class; a named SQL query outside of a <literal>class
</literal> element acts as a column data projection.
</para>
<example id="jpa_overview_sqlquery_namedex">
<title>Named SQL Queries</title>
<programlisting>
<![CDATA[<?xml version="1.0"?>
<jdoquery>
<query name="salesReport" language="javax.persistence.query.SQL">
SELECT TITLE, PRICE * COPIES FROM MAG
</query>
<package name="org.mag">
<class name="Magazine">
<query name="findByTitle" language="javax.persistence.query.SQL">
SELECT * FROM MAG WHERE TITLE = ?
</query>
</class>
</package>
</jdoquery>]]>
</programlisting>
<para>
The <literal>salesReport</literal> query above returns the title
and revenue generated for each <classname>Magazine</classname>.
Because it is a projection, it does not have a candidate class, and
so we specify it at the root level.
</para>
<para>
The <literal>findByTitle</literal> query returns the <classname>
Magazine</classname> with the title given on execution. The code
below executes both queries.
</para>
<programlisting>
EntityManager em = ...;
Query query = em.newNamedQuery (null, "salesReport");
List sales = query.getResultList ();
for (Iterator itr = sales.iterator (); itr.hasNext ();)
{
Object[] salesData = (Object[]) itr.next ();
processSalesData ((String) salesData[0], (Number) salesData[1]);
}
query = em.newNamedQuery (Magazine.class, "findByTitle");
query.setUnique (true);
Magazine jdj = (Magazine) query.execute ("JDJ");
</programlisting>
</example>
</section>
<section id="jpa_overview_sqlquery_conclusion">
<title>Conclusion</title>
<para>
If you've used relational databases extensively, you might be tempted
to perform all your JPA queries with SQL. Try to resist this
temptation. SQL queries tie your application to the particulars of
your current table model and database vendor. If you stick with JPQL,
on the other hand, you can port your application to other schemas and
database vendors without any changes to your code. Additionally,
most JPA implementations already produce highly optimized SQL from
your JPQL filters, and many are able to cache JPQL query results
for added performance.
</para>
</section>
-->
</chapter>

View File

@ -0,0 +1,234 @@
<chapter id="jpa_overview_trans">
<title>Transaction</title>
<indexterm zone="jpa_overview_trans">
<primary>transactions</primary>
<seealso>Transaction</seealso>
</indexterm>
<para>
Transactions are critical to maintaining data integrity. They are
used to group operations into units of work that act in an
all-or-nothing fashion. Transactions have the following qualities:
</para>
<itemizedlist>
<listitem>
<para><indexterm><primary>atomicity</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>atomicity</secondary></indexterm><emphasis>Atomicity</emphasis>. Atomicity refers to the
all-or-nothing property of transactions. Either every
data update in the transaction completes successfully, or they
all fail, leaving the datastore in its original state. A
transaction cannot be only partially successful.
</para>
</listitem>
<listitem>
<para><indexterm><primary>consistency</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>consistency</secondary></indexterm><emphasis>Consistency</emphasis>. Each transaction takes the
datastore from one consistent state to another consistent
state.
</para>
</listitem>
<listitem>
<para><indexterm><primary>isolation</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>isolation</secondary></indexterm><emphasis>Isolation</emphasis>. Transactions are isolated from
each other. When you are reading persistent data in one
transaction, you cannot "see" the changes that are being made
to that data in other transactions. Similarly,
the updates you make in one transaction cannot conflict with
updates made in concurrent transactions. The form of
conflict resolution employed depends on whether you are using
pessimistic or optimistic transactions. Both types are
described later in this chapter.
</para>
</listitem>
<listitem>
<para><indexterm><primary>durability</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>durability</secondary></indexterm><emphasis>Durability</emphasis>. The effects of successful
transactions are durable; the updates made to persistent data
last for the lifetime of the datastore.
</para>
</listitem>
</itemizedlist>
<para><indexterm><primary>ACID</primary><seealso>transactions</seealso></indexterm><indexterm><primary>transactions</primary><secondary>ACID</secondary></indexterm>
Together, these qualities are called the ACID properties of
transactions. To understand why these properties are so important
to maintaining data integrity, consider the following example:
</para>
<para>
Suppose you create an application to manage bank accounts. The
application includes a method to transfer funds from one user to
another, and it looks something like this:
</para>
<programlisting format="linespecific">
public void transferFunds (User from, User to, double amnt)
{
from.decrementAccount (amnt);
to.incrementAccount (amnt);
}
</programlisting>
<para>
Now suppose that user Alice wants to transfer 100 dollars to user Bob.
No problem; you simply invoke your
<methodname>transferFunds</methodname> method, supplying Alice in the
<literal>from</literal> parameter, Bob in the <literal>to</literal>
parameter, and <literal>100.00</literal> as the <literal>amnt</literal>.
The first line of the method is executed, and 100 dollars is subtracted
from Alice's account. But then, something goes wrong. An unexpected
exception occurs, or the hardware fails, and your method never
completes.
</para>
<para>
You are left with a situation in which the 100 dollars has simply
disappeared. Thanks to the first line of your method, it is no longer
in Alice's account, and yet it was never transferred to Bob's account
either. The datastore is in an inconsistent state.
</para>
<para>
The importance of transactions should now be clear. If the two lines
of the <methodname>transferFunds</methodname> method had been placed
together in a transaction, it would be impossible for only the
first line to succeed. Either the funds would be transferred
properly or they would not be transferred at all, and an exception
would be thrown. Money could never vanish into thin air, and the data
store could never get into an inconsistent state.
</para>
<section id="jpa_overview_trans_types">
<title>Transaction Types</title>
<indexterm zone="jpa_overview_trans_types">
<primary>transactions</primary>
<secondary>types</secondary>
</indexterm>
<para>
There are two major types of transactions: pessimistic transactions
and optimistic transactions. Each type has both advantages and
disadvantages.
</para>
<para><indexterm><primary>transactions</primary><secondary>pessimistic</secondary></indexterm><indexterm><primary>pessimistic transactions</primary><see>transactions, pessimistic</see></indexterm><indexterm><primary>deadlock</primary><seealso>transactions</seealso></indexterm>
Pessimistic transactions generally lock the datastore records they
act on, preventing other concurrent transactions from using the
same data. This avoids conflicts between transactions, but
consumes database resources. Additionally, locking records
can result in <emphasis>deadlock</emphasis>, a situation in which two
transactions are both waiting for the other to release its locks before
completing. The results of a deadlock are datastore-dependent;
usually one transaction is forcefully rolled back after some specified
timeout interval, and an exception is thrown.
</para>
<para><indexterm><primary>transactions</primary><secondary>datastore</secondary></indexterm><indexterm><primary>datastore transactions</primary><see>transactions, datastore</see></indexterm>
This document will often use the term <emphasis>datastore</emphasis>
transaction in place of <emphasis>pessimistic</emphasis> transaction.
This is to acknowledge that some datastores do not support pessimistic
semantics, and that the exact meaning of a non-optimistic JPA
transaction is dependent on the datastore. Most of the
time, a datastore transaction is equivalent to a pessimistic
transaction.
</para>
<para><indexterm><primary>transactions</primary><secondary>optimistic</secondary></indexterm><indexterm><primary>optimistic transactions</primary><see>transactions, optimistic</see></indexterm>
Optimistic transactions consume less resources than
pessimistic/datastore transactions, but only at the expense of
reliability. Because optimistic transactions do not lock datastore
records, two transactions might change the same persistent information
at the same time, and the conflict will not be detected until
the second transaction attempts to flush or commit. At this time, the
second transaction will realize that another transaction has
concurrently modified the same records (usually through a timestamp
or versioning system), and will throw an appropriate exception.
Note that optimistic transactions still maintain data integrity;
they are simply more likely to fail in heavily concurrent
situations.
</para>
<para>
Despite their drawbacks, optimistic transactions are the best choice
for most applications. They offer better performance, better
scalability, and lower risk of hanging due to deadlock.
</para>
<note>
<para>
OpenJPA uses optimistic semantics by default, but supports both
optimistic and datastore transactions.
OpenJPA also offers advanced locking and versioning APIs for
fine-grained control over database resource allocation and object
versioning. See <xref linkend="ref_guide_locking"/> and
<xref linkend="ref_guide_lock_groups"/> of the Reference Guide for
details on locking. <xref linkend="jpa_overview_meta_version"/>
of this document covers standard object versioning.
<!-- ### EJBDOC : link additional strats when available from JPA -->
</para>
</note>
</section>
<section id="jpa_overview_trans_ejb3">
<title>The EntityTransaction Interface</title>
<indexterm zone="jpa_overview_trans_ejb3">
<primary>Transaction</primary>
<seealso>transactions</seealso>
</indexterm>
<mediaobject>
<imageobject>
<!-- PNG image data, 193 x 157 (see README) -->
<imagedata fileref="img/jpa-transaction.png" width="129px"/>
</imageobject>
</mediaobject>
<para>
JPA integrates with your container's <emphasis>managed
</emphasis> transactions, allowing you to use the container's
declarative transaction demarcation and its Java Transaction API (JTA)
implementation for transaction management.
Outside of a container, though, you must demarcate transactions
manually through JPA. The <classname>
EntityTransaction</classname> interface controls unmanaged transactions
in JPA.
</para>
<programlisting format="linespecific">
public void begin ();
public void commit ();
public void rollback ();
</programlisting>
<para><indexterm><primary>Transaction</primary><secondary>demarcation</secondary></indexterm><indexterm><primary>transactions</primary><secondary>demarcating</secondary></indexterm><indexterm><primary>Transaction</primary><secondary>begin</secondary></indexterm><indexterm><primary>Transaction</primary><secondary>commit</secondary></indexterm><indexterm><primary>Transaction</primary><secondary>rollback</secondary></indexterm>
The <methodname>begin</methodname>, <methodname>commit</methodname>,
and <methodname>rollback</methodname> methods demarcate transaction
boundaries. The methods should be self-explanatory:
<methodname>begin</methodname> starts a transaction,
<methodname>commit</methodname> attempts to commit the transaction's
changes to the datastore, and <methodname>rollback</methodname>
aborts the transaction, in which case the datastore is
"rolled back" to its previous state. JPA
implementations will automatically roll back transactions if any
exception is thrown during the commit process.
</para>
<para>
Unless you are using an extended persistence context, committing or
rolling back also ends the persistence context. All managed entites
will be detached from the <classname>EntityManager</classname>.
</para>
<programlisting format="linespecific">
public boolean isActive ();
</programlisting>
<para><indexterm><primary>Transaction</primary><secondary>isActive</secondary></indexterm>
Finally, the <methodname>isActive</methodname> method returns
<literal>true</literal> if the transaction is in progress
(<methodname>begin</methodname> has been called more recently than
<methodname>commit</methodname> or
<methodname>rollback</methodname>), and <literal>false</literal>
otherwise.
</para>
<example id="jpa_overview_trans_group">
<title>Grouping Operations with Transactions</title>
<programlisting format="linespecific">
public void transferFunds (EntityManager em, User from, User to, double amnt)
{
// note: it would be better practice to move the transaction demarcation
// code out of this method, but for the purposes of example...
Transaction trans = em.getTransaction ();
trans.begin ();
try
{
from.decrementAccount (amnt);
to.incrementAccount (amnt);
trans.commit ();
}
catch (RuntimeException re)
{
if (trans.isActive ())
trans.rollback (); // or could attempt to fix error and retry
throw re;
}
}
</programlisting>
</example>
</section>
</chapter>

View File

@ -0,0 +1,371 @@
<chapter id="jpa_overview_why">
<title>Why JPA?</title>
<indexterm zone="jpa_overview_why">
<primary>JPA</primary>
<secondary>why</secondary>
</indexterm>
<para>
Java developers who need to store and retrieve persistent
data already have several options available to them:
serialization, JDBC, JDO, proprietary object-relational mapping tools,
object databases, and EJB 2 entity beans. Why introduce yet
another persistence framework? The answer to this question is that with
the exception of JDO, each of the aforementioned persistence solutions
has severe limitations. JPA attempts to overcome these
limitations, as illustrated by the table below.
</para>
<table tocentry="1">
<title>Persistence Mechanisms</title>
<tgroup cols="8" align="left" colsep="1" rowsep="1">
<colspec colname="sup"/>
<colspec colname="ser"/>
<colspec colname="jdbc"/>
<colspec colname="or"/>
<colspec colname="objdb"/>
<colspec colname="ejb2"/>
<colspec colname="jdo"/>
<colspec colname="ejb3"/>
<thead>
<row>
<entry colname="sup">Supports:</entry>
<entry colname="ser">Serialization</entry>
<entry colname="jdbc">JDBC</entry>
<entry colname="or">ORM</entry>
<entry colname="objdb">ODB</entry>
<entry colname="ejb2">EJB 2</entry>
<entry colname="jdo">JDO</entry>
<entry colname="ejb3">JPA</entry>
</row>
</thead>
<tbody>
<row>
<entry colname="sup">Java Objects</entry>
<entry colname="ser">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdbc">No</entry>
<entry colname="or">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="objdb">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb2">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
<row>
<entry colname="sup">Advanced OO Concepts</entry>
<entry colname="ser">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdbc">No</entry>
<entry colname="or">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="objdb">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb2">No</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
<row>
<entry colname="sup">Transactional Integrity</entry>
<entry colname="ser">No</entry>
<entry colname="jdbc">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="or">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="objdb">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb2">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
<row>
<entry colname="sup">Concurrency</entry>
<entry colname="ser">No</entry>
<entry colname="jdbc">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="or">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="objdb">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb2">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
<row>
<entry colname="sup">Large Data Sets</entry>
<entry colname="ser">No</entry>
<entry colname="jdbc">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="or">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="objdb">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb2">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
<row>
<entry colname="sup">Existing Schema</entry>
<entry colname="ser">No</entry>
<entry colname="jdbc">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="or">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="objdb">No</entry>
<entry colname="ejb2">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
<row>
<entry colname="sup">
Relational and Non-Relational Stores
</entry>
<entry colname="ser">No</entry>
<entry colname="jdbc">No</entry>
<entry colname="or">No</entry>
<entry colname="objdb">No</entry>
<entry colname="ejb2">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">No</entry>
</row>
<row>
<entry colname="sup">Queries</entry>
<entry colname="ser">No</entry>
<entry colname="jdbc">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="or">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="objdb">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb2">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
<row>
<entry colname="sup">Strict Standards / Portability</entry>
<entry colname="ser">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdbc">No</entry>
<entry colname="or">No</entry>
<entry colname="objdb">No</entry>
<entry colname="ejb2">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
<row>
<entry colname="sup">Simplicity</entry>
<entry colname="ser">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="jdbc">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="or">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="objdb">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb2">No</entry>
<entry colname="jdo">
<emphasis role="bold">Yes</emphasis>
</entry>
<entry colname="ejb3">
<emphasis role="bold">Yes</emphasis>
</entry>
</row>
</tbody>
</tgroup>
</table>
<itemizedlist>
<listitem>
<para><indexterm><primary>serialization</primary></indexterm><indexterm><primary>JPA</primary><secondary>vs serialization</secondary></indexterm><emphasis>Serialization</emphasis> is Java's
built-in mechanism for transforming an object graph into a
series of bytes, which can then be sent over the network or
stored in a file. Serialization is very easy to use,
but it is also very limited. It must store and retrieve the
entire object graph at once, making it unsuitable for
dealing with large amounts of data. It cannot undo changes
that are made to objects if an error occurs while updating
information, making it unsuitable for applications that
require strict data integrity. Multiple threads or programs
cannot read and write the same serialized data concurrently
without conflicting with each other. It provides no query
capabilities. All these factors make serialization useless
for all but the most trivial persistence needs.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Java Database Connectivity</primary><see>JDBC</see></indexterm><indexterm><primary>JDBC</primary></indexterm><indexterm><primary>JPA</primary><secondary>vs JDBC</secondary></indexterm>
Many developers use the
<emphasis>Java Database Connectivity</emphasis> (JDBC) APIs to
manipulate persistent data in relational databases. JDBC
overcomes most of the shortcomings of serialization:
it can handle large amounts of data, has mechanisms to ensure
data integrity, supports concurrent access to information, and
has a sophisticated query language in SQL. Unfortunately, JDBC
does not duplicate serialization's ease of use. The relational
paradigm used by JDBC was not designed for storing objects,
and therefore forces you to either abandon
object-oriented programming for the portions of your code
that deal with persistent data, or to find a way of mapping
object-oriented concepts like inheritance to relational
databases yourself.
</para>
</listitem>
<listitem>
<para><indexterm><primary>object-relational mapping</primary><see>ORM</see></indexterm><indexterm><primary>ORM</primary></indexterm><indexterm><primary>JPA</primary><secondary>vs ORM products</secondary></indexterm>
There are many proprietary software products that can perform the
mapping between objects and relational database tables for you.
These <emphasis>object-relational mapping</emphasis> (ORM)
frameworks allow you to focus on the object model and not concern
yourself with the mismatch between
the object-oriented and relational paradigms. Unfortunately,
each of these product has its own set of APIs.
Your code becomes tied to the proprietary interfaces of a single
vendor. If the vendor raises prices, fails to fix show-stopping
bugs, or falls behind in features, you cannot switch to another
product without rewriting all of your persistence code. This is
referred to as vendor lock-in.
</para>
</listitem>
<listitem>
<para><indexterm><primary>object database</primary><see>ODB</see></indexterm><indexterm><primary>ODB</primary></indexterm><indexterm><primary>JPA</primary><secondary>vs ODBs</secondary></indexterm><indexterm><primary>ODBMG</primary></indexterm>
Rather than map objects to relational databases, some software
companies have developed a form of database designed
specifically to store objects. These
<emphasis>object databases</emphasis> (ODBs) are often much
easier to use than object-relational mapping software.
The Object Database Management Group (ODMG) was formed to create
a standard API for accessing object databases; few object
database vendors, however, comply with the ODMG's
recommendations. Thus, vendor lock-in plagues object databases
as well. Many companies are also hesitant to switch from
tried-and-true relational systems to the relatively unknown object
database technology. Fewer data-analysis tools are available
for object database systems, and there are vast quantities of
data already stored in older relational databases. For all of
these reasons and more, object databases have not caught on
as well as their creators hoped.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Enterprise Java Beans</primary><see>EJB</see></indexterm><indexterm><primary>EJB</primary></indexterm><indexterm><primary>JPA</primary><secondary>vs EJB 2</secondary></indexterm>
The Enterprise Edition of the Java platform introduced entity
Enterprise Java Beans (EJBs). EJB 2.x entities are components that
represent persistent information in a datastore. Like
object-relational mapping solutions, EJB 2.x entities provide
an object-oriented view of persistent data. Unlike
object-relational software, however, EJB 2.x entities are not
limited to relational databases; the persistent information they
represent may come from an Enterprise Information System (EIS) or
other storage device. Also, EJB 2.x entities use a strict standard,
making them portable across vendors. Unfortunately, the EJB 2.x
standard is somewhat limited in the object-oriented concepts it can
represent. Advanced features like inheritance, polymorphism, and
complex relations are absent. Additionally, EBJ 2.x entities are
difficult to code, and they require heavyweight and often expensive
application servers to run.
</para>
</listitem>
<listitem>
<para><indexterm><primary>JDO</primary></indexterm><indexterm><primary>JPA</primary><secondary>vs JDO</secondary></indexterm>
The JDO specification uses an API that is strikingly similar to
JPA. JDO, however, supports non-relational databases,
a feature that some argue dilutes the specification.
</para>
</listitem>
</itemizedlist>
<para><indexterm><primary>JPA</primary></indexterm>
JPA combines the best features from each of the persistence
mechanisms listed above. Creating entities under JPA
is as simple as creating serializable classes. JPA supports the
large data sets, data consistency, concurrent use, and query capabilities of
JDBC. Like object-relational software and object databases, JPA
allows the use of advanced object-oriented concepts such as inheritance.
JPA avoids vendor lock-in by relying on a strict specification
like JDO and EJB 2.x entities. JPA focuses on relational
databases. And like JDO, JPA is extremely easy to use.
</para>
<note>
<para>
OpenJPA typically stores data in relational databases, but can be
customized for use with non-relational datastores as well.
</para>
</note>
<para>
JPA is not ideal for every application. For many applications,
though, it provides an exciting alternative to other persistence mechanisms.
</para>
</chapter>

View File

@ -0,0 +1,39 @@
<appendix id="jpa_resources">
<title>JPA Resources</title>
<itemizedlist>
<listitem>
<para>
<ulink url="http://java.sun.com/aboutJava/communityprocess/jsr/jsr_220_dataobj.html">
EJB 3 JSR page</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="http://java.sun.com/products/ejb">Sun EJB page</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="http://java.sun.com/javaee/5/docs/api/index.html">Locally mirrored
javax.persistence Javadoc</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="../../api/index.html">OpenJPA API Javadoc</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="../apidocs/index.html">Full OpenJPA Javadoc</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="Persistence.pdf">Locally mirrored JPA
specification</ulink>
</para>
</listitem>
</itemizedlist>
</appendix>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,61 @@
<chapter id="openjpa_intro">
<title>OpenJPA <phrase>JPA</phrase></title>
<indexterm zone="openjpa_intro">
<primary>OpenJPA <phrase>JPA</phrase></primary>
</indexterm>
<para>
OpenJPA is Apache's implementation of Sun's
<phrase>Java Persistence API (JPA) specification</phrase>
for the transparent persistence of Java objects.
This document provides an overview of
<phrase>the JPA standard</phrase>
and technical details on the use of OpenJPA <phrase>JPA</phrase>.
</para>
<para>
To quickly get started with JPA, you may want to begin at
<xref linkend="jpa_tutorial"/>.
If you would prefer to start with an introduction to the concepts of JPA,
begin with <xref linkend="jpa_overview_intro"/>.
</para>
<section id="openjpa_intro_about">
<title>About This Document</title>
<para>
This document is intended for OpenJPA users. It is divided into several
parts:
</para>
<itemizedlist>
<listitem>
<para>
The <link linkend="jpa_overview_intro">JPA Overview</link>
describes the fundamentals of JPA.
</para>
</listitem>
<listitem>
<para>
In the <link linkend="tutorials">OpenJPA <phrase>JPA</phrase>
Tutorials</link> you will develop simple persistent applications
using OpenJPA. Through the tutorials' hands-on approach, you
will become comfortable with the core tools and development
processes under OpenJPA <phrase>JPA</phrase>.
</para>
</listitem>
<listitem>
<para>
The <link linkend="ref_guide_intro">OpenJPA <phrase>JPA</phrase>
Reference Guide</link> contains detailed documentation on all
aspects of OpenJPA <phrase>JPA</phrase>. Browse through this guide to
familiarize yourself with the many advanced features and
customization opportunities OpenJPA provides. Later, you can use
the guide when you need details on a specific aspect of OpenJPA
<phrase>JPA</phrase>.
</para>
</listitem>
</itemizedlist>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,224 @@
<chapter id="ref_guide_deploy">
<title>Deployment</title>
<para>
OpenJPA deployment includes choosing a factory deployment strategy,
and in a managed environment, optionally integrating with your application
server's managed and XA transactions. This chapter examines each aspect
of deployment in turn.
</para>
<section id="ref_guide_deploy_factory">
<title>Factory Deployment</title>
<para>
OpenJPA offers several
<phrase><classname>EntityManagerFactory</classname></phrase>
deployment options.
</para>
<section id="ref_guide_deploy_factory_standalone">
<title>Standalone Deployment</title>
<indexterm zone="ref_guide_deploy_factory_standalone">
<primary>deployment</primary>
<secondary>standalone</secondary>
<seealso>Persistence</seealso>
</indexterm>
<para>
The JPA Overview describes the
<classname>javax.persistence.Persistence</classname> class. You
can use <classname>Persistence</classname> to obtain
<classname>EntityManagerFactory</classname> instances, as
demonstrated in <xref linkend="jpa_overview_persistence"/>.
OpenJPA also extends <classname>Persistence</classname> to add
additional <classname>EntityManagerFactory</classname>
creation methods. The
<classname>org.apache.openjpa.persistence.OpenJPAPersistence</classname> class
<ulink url="../../api/openjpa/persistence/OpenJPAPersistence.html">
Javadoc</ulink> details these extensions.
</para>
<para>
After obtaining the factory, you can cache it for all
<phrase><classname>EntityManager</classname></phrase>
creation duties.
</para>
</section>
<section id="ref_guide_deploy_inject">
<title>EntityManager Injection</title>
<!-- ### EJBDOC -->
<para>
To be decided.
</para>
</section>
<section id="ref_guide_deploy_jca_ejb">
<title>OpenJPA JCA Deployment</title>
<indexterm zone="ref_guide_deploy_jca_ejb">
<primary>deployment</primary>
<secondary>JCA</secondary>
<seealso>JCA</seealso>
</indexterm>
<indexterm zone="ref_guide_deploy_jca_ejb">
<primary>JCA</primary>
<secondary>deployment</secondary>
</indexterm>
<para>
OpenJPA can deploy OpenJPA through the Java Connector Architecture
(JCA) in any JCA-compliant application server that supports
JDK 1.5 (all EJB 3 implementations require JDK 1.5). We present
the deployment steps for the most common servers below.
</para>
<section id="ref_guide_deploy_jca_jpa_weblogic9">
<title>WebLogic 9</title>
<indexterm zone="ref_guide_deploy_jca_jpa_weblogic9">
<primary>Weblogic</primary>
</indexterm>
<indexterm zone="ref_guide_deploy_jca_jpa_weblogic9">
<primary>JCA</primary>
<secondary>Weblogic 9</secondary>
</indexterm>
<para><!-- ### JDO2MIG : everything in system path for now -->
First, ensure that your JDBC driver is in your system classpath.
In addition, you will be adding the OpenJPA and specification API
jars to the system classpath. You can accomplish this by
editing <filename>startWebLogic.sh/.cmd</filename>.
</para>
<warning>
<para>Currently WebLogic ships with an old version
of the EJB 3 libraries. Be sure to put
<filename>org.apache.openjpa.jar</filename> in the <emphasis>beginning
</emphasis> of the <literal>CLASSPATH</literal>.</para>
</warning>
<para>
The next step is to deploy
<filename>openjpa-persistence.rar</filename> from the
<filename>jca/persistence</filename> directory of your OpenJPA
installation. Copy this file to the <filename>autodeploy
</filename> directory of your domain.
</para>
<para>
We will now extract <filename>META-INF/ra.xml</filename>
and <filename>META-INF/weblogic-ra.xml</filename>
to edit our configuration:
</para>
<programlisting format="linespecific">
jar xvf openjpa-ejb.rar META-INF/ra.xml META-INF/weblogic-ra.xml
</programlisting>
<para>
Now you should configure OpenJPA JCA by editing
<filename>META-INF/ra.xml</filename> substituting
<literal>config-property-value</literal> stanzas
with your own values. You can comment out
properties (config-property stanzas) which you are
not using or you can leave them at their default settings.
Edit <filename>META-INF/weblogic-ra.xml</filename>
to configure the JNDI location to which you
want OpenJPA to be bound.
</para>
<para>
Now we can re-jar the manifest files back into the
<filename>RAR</filename> file.
</para>
<programlisting format="linespecific">
jar uvf openjpa-ejb.rar META-INF/ra.xml META-INF/weblogic-ra.xml
rm META-INF/ra.xml META-IN/weblogic-ra.xml
rmdir META-INF
</programlisting>
<para>
Now you can start WebLogic and WebLogic should
deploy OpenJPA for you. If you have installed OpenJPA correctly,
at this point, one should be able to see OpenJPA bound to the
JNDI location which you specified earlier.
</para>
</section>
</section>
</section>
<section id="ref_guide_enterprise_xa">
<title>XA Transactions</title>
<indexterm zone="ref_guide_enterprise_xa">
<primary>transactions</primary>
<secondary>XA</secondary>
</indexterm>
<indexterm>
<primary>XA transactions</primary>
<see>transactions</see>
</indexterm>
<para>
The X/Open Distributed Transaction Processing (X/Open DTP)
model, designed by <ulink url="http://www.xopen.org">Open Group</ulink>
(a vendor consortium), defines a standard communication architecture
that provides the following:
</para>
<itemizedlist>
<listitem>
<para>
Concurrent execution of applications on shared resources.
</para>
</listitem>
<listitem>
<para>
Coordination of transactions across applications.
</para>
</listitem>
<listitem>
<para>
Components, interfaces, and protocols that define the
architecture and provide portability of applications.
</para>
</listitem>
<listitem>
<para>Atomicity of transaction systems.</para>
</listitem>
<listitem>
<para>
Single-thread control and sequential function-calling.
</para>
</listitem>
</itemizedlist>
<para>
The X/Open DTP XA standard defines the application programming
interfaces that a resource manager uses to communicate
with a transaction manager. The XA interfaces enable resource
managers to join transactions, to perform two-phase commit,
and to recover in-doubt transactions following a failure.
</para>
<section id="ref_guide_enterprise_xa_req">
<title>Using OpenJPA with XA Transactions</title>
<para>
OpenJPA supports XA-compliant transactions when used in a properly
configured managed environment. The following components are
required:
</para>
<itemizedlist>
<listitem>
<para>
A managed environment that provides an XA compliant
transaction manager. Examples of this are application
servers such as JBoss and WebLogic.
</para>
</listitem>
<listitem>
<para>
Instances of a <classname>javax.sql.XADataSource</classname>
for each of the <classname>DataSource</classname>s that
OpenJPA will use.
</para>
</listitem>
</itemizedlist>
<para>
Given these components, setting up OpenJPA to participate in
distributed transactions is a simple two-step process:
</para>
<orderedlist>
<listitem>
<para>
Point OpenJPA at an enlisted
<classname>XADataSource</classname>, and configure a
second non-enlisted data source.
See <xref linkend="ref_guide_dbsetup_thirdparty_enlist"/>.
</para>
</listitem>
</orderedlist>
</section>
</section>
</chapter>

View File

@ -0,0 +1,419 @@
<chapter id="ref_guide_integration">
<title>Third Party Integration</title>
<para>
OpenJPA provides a number of mechanisms for integrating with third-party
tools. The following chapter will illustrate these integration features.
</para>
<section id="ref_guide_integration_ant">
<title>Apache Ant</title>
<indexterm zone="ref_guide_integration_ant">
<primary>Ant</primary>
</indexterm>
<para>
Ant is a very popular tool for building Java projects. It is similar to
the <literal>make</literal> command, but is Java-centric and has
more modern features. Ant is open source, and can be downloaded
from Apache's Ant web page at
<ulink url="http://jakarta.apache.org/ant/">
http://jakarta.apache.org/ant/</ulink>.
Ant has become the de-facto standard build tool for Java, and
many commercial integrated development environments provide
some support for using ant build files. The remainder of this
section assumes familiarity with writing Ant
<filename>build.xml</filename> files.
</para>
<para>
OpenJPA provides pre-built Ant task definitions for all bundled tools:
</para>
<itemizedlist>
<listitem>
<para>
<link linkend="ref_guide_integration_enhance">Enhancer
Task</link>
</para>
</listitem>
<listitem>
<para>
<link linkend="ref_guide_integration_appidtool">Application
Identity Tool Task</link>
</para>
</listitem>
<listitem>
<para>
<link linkend="ref_guide_integration_mappingtool">Mapping
Tool Task</link>
</para>
</listitem>
<listitem>
<para>
<link linkend="ref_guide_integration_revmappingtool">Reverse
Mapping Tool Task</link>
</para>
</listitem>
<listitem>
<para>
<link linkend="ref_guide_integration_schematool">Schema Tool
Task</link>
</para>
</listitem>
</itemizedlist>
<para>
The source code for all the ant tasks is provided with the distribution
under the <filename>src</filename> directory. This allows you
to customize various aspects of the ant tasks in order to better
integrate into your development environment.
</para>
<section id="ref_guide_integration_conf">
<title>Common Ant Configuration Options</title>
<indexterm>
<primary>Ant</primary>
<secondary>configuration options</secondary>
</indexterm>
<para>
All OpenJPA tasks accept a nested <literal>config</literal>
element, which defines the configuration environment in which
the specified task will run. The attributes for the
<literal>config</literal> tag are defined by the
<ulink url="../apidocs/org/apache/openjpa/jdbc/conf/JDBCConfiguration.html"><classname>JDBCConfiguration</classname></ulink> bean methods.
Note that excluding the <literal>config</literal> element
will cause the Ant task to use the default system configuration
mechanism, such as the configuration defined in the
<phrase><filename>org.apache.openjpa.xml</filename></phrase>
file.
</para>
<para>
Following is an example of how to use the nested
<literal>config</literal> tag in a <filename>build.xml</filename>
file:
</para>
<example id="ref_guide_integration_conf_config">
<title>Using the &lt;config&gt; Ant Tag</title>
<programlisting format="linespecific">
&lt;mappingtool&gt;
&lt;fileset dir="${basedir}"&gt;
&lt;include name="**/model/*.java" /&gt;
&lt;/fileset&gt;
&lt;config connectionUserName="scott" connectionPassword="tiger"
connectionURL="jdbc:oracle:thin:@saturn:1521:solarsid"
connectionDriverName="oracle.jdbc.driver.OracleDriver" /&gt;
&lt;/mappingtool&gt;
</programlisting>
</example>
<para>
It is also possible to specify a <literal>properties</literal>
or <literal>propertiesFile</literal> attribute on the
<literal>config</literal> tag, which will be used to
locate a properties resource or file. The resource will be
loaded relative to the current CLASSPATH.
</para>
<example id="ref_guide_integration_props">
<title>Using the Properties Attribute of the &lt;config&gt;
Tag</title>
<programlisting format="linespecific">
&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;/mappingtool&gt;
</programlisting>
</example>
<example id="ref_guide_integration_propsfile">
<title>Using the PropertiesFile Attribute of the &lt;config&gt;
Tag</title>
<programlisting format="linespecific">
&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;/mappingtool&gt;
</programlisting>
</example>
<para>
Tasks also accept a nested <literal>classpath</literal>
element, which you can use in place of the default classpath.
The <literal>classpath</literal> argument behaves the same
as it does for Ant's standard <literal>javac</literal>
element. It is sometimes the case that projects are compiled
to a separate directory than the source tree. If the target
path for compiled classes is not included in the project's
classpath, then a <literal>classpath</literal> element
that includes the target class directory needs to be included so
the enhancer and mapping tool can locate the relevant classes.
</para>
<para>
Following is an example of using a <literal>classpath</literal> tag:
</para>
<example id="ref_guide_integration_conf_classpath">
<title>Using the &lt;classpath&gt; Ant Tag</title>
<programlisting format="linespecific">
&lt;openjpac&gt;
&lt;fileset dir="${basedir}/source"&gt;
&lt;include name="**/model/*.java" /&gt;
&lt;/fileset&gt;
&lt;classpath&gt;
&lt;pathelement location="${basedir}/classes"/&gt;
&lt;pathelement location="${basedir}/source"/&gt;
&lt;pathelement path="${java.class.path}"/&gt;
&lt;/classpath&gt;
&lt;/openjpac&gt;
</programlisting>
</example>
<para>
Finally, tasks that invoke code-generation tools like the
application identity tool and reverse mapping tool accept a nested
<literal>codeformat</literal> element. See the code formatting
documentation in <xref linkend="ref_guide_conf_devtools_format"/>
for a list of code formatting attributes.
</para>
<example id="ref_guide_integration_conf_codeformat">
<title>Using the &lt;codeformat&gt; Ant Tag</title>
<programlisting format="linespecific">
&lt;reversemappingtool package="com.xyz.jdo" directory="${basedir}/src"&gt;
&lt;codeformat tabSpaces="4" spaceBeforeParen="true" braceOnSameLine="false"/&gt;
&lt;/reversemappingtool&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_integration_enhance">
<title>Enhancer Ant Task</title>
<indexterm zone="ref_guide_integration_enhance">
<primary>Ant</primary>
<secondary>enhancer task</secondary>
</indexterm>
<indexterm zone="ref_guide_integration_enhance">
<primary>enhancer</primary>
<secondary>Ant task</secondary>
</indexterm>
<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>.
</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.
</para>
<para>
Following is an example of using the enhancer task
in a <filename>build.xml</filename> file:
</para>
<example id="ref_guide_integration_enhance_task">
<title>Invoking the Enhancer from Ant</title>
<programlisting format="linespecific">
&lt;target name="enhance"&gt;
&lt;!-- define the openjpac task; this can be done at the top of the --&gt;
&lt;!-- build.xml file, so it will be available for all targets --&gt;
&lt;taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask"/&gt;
&lt;!-- invoke enhancer on all .jdo files below the current directory --&gt;
&lt;openjpac&gt;
&lt;fileset dir="."&gt;
&lt;include name="**/model/*.java" /&gt;
&lt;/fileset&gt;
&lt;/openjpac&gt;
&lt;/target&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_integration_appidtool">
<title>Application Identity Tool Ant Task</title>
<indexterm zone="ref_guide_integration_enhance">
<primary>Ant</primary>
<secondary>application identity tool task</secondary>
</indexterm>
<indexterm zone="ref_guide_integration_enhance">
<primary>application identity tool</primary>
<secondary>Ant task</secondary>
</indexterm>
<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>.
</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.
</para>
<para>
Following is an example of using the application identity tool task
in a <filename>build.xml</filename> file:
</para>
<example id="ref_guide_integration_appidtool_task">
<title>Invoking the Application Identity Tool from Ant</title>
<programlisting format="linespecific">
&lt;target name="appids"&gt;
&lt;!-- define the appidtool task; this can be done at the top of --&gt;
&lt;!-- the build.xml file, so it will be available for all targets --&gt;
&lt;taskdef name="appidtool" classname="org.apache.openjpa.ant.ApplicationIdToolTask"/&gt;
&lt;!-- invoke tool on all .jdo files below the current directory --&gt;
&lt;appidtool&gt;
&lt;fileset dir="."&gt;
&lt;include name="**/model/*.java" /&gt;
&lt;/fileset&gt;
&lt;codeformat spaceBeforeParen="true" braceOnSameLine="false"/&gt;
&lt;/appidtool&gt;
&lt;/target&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_integration_mappingtool">
<title>Mapping Tool Ant Task</title>
<indexterm zone="ref_guide_integration_mappingtool">
<primary>Ant</primary>
<secondary>mapping tool task</secondary>
</indexterm>
<indexterm zone="ref_guide_integration_mappingtool">
<primary>mapping tool</primary>
<secondary>Ant task</secondary>
</indexterm>
<para>
The mapping tool task allows you to directly invoke the
mapping tool from within the Ant build process. It is useful for
making sure that the database schema and 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>.
</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.
</para>
<para>
Following is an example of a <filename>build.xml</filename>
target that invokes the mapping tool:
</para>
<example id="ref_guide_integration_mappingtool_task">
<title>Invoking the Mapping Tool from Ant</title>
<programlisting format="linespecific">
&lt;target name="refresh"&gt;
&lt;!-- define the mappingtool task; this can be done at the top of --&gt;
&lt;!-- the build.xml file, so it will be available for all targets --&gt;
&lt;taskdef name="mappingtool" classname="org.apache.openjpa.jdbc.ant.MappingToolTask"/&gt;
&lt;!-- add the schema components for all .jdo files below the --&gt;
&lt;!-- current directory --&gt;
&lt;mappingtool action="buildSchema"&gt;
&lt;fileset dir="."&gt;
&lt;include name="**/*.jdo" /&gt;
&lt;/fileset&gt;
&lt;/mappingtool&gt;
&lt;/target&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_integration_revmappingtool">
<title>Reverse Mapping Tool Ant Task</title>
<indexterm zone="ref_guide_integration_revmappingtool">
<primary>Ant</primary>
<secondary>reverse mapping tool task</secondary>
</indexterm>
<indexterm zone="ref_guide_integration_revmappingtool">
<primary>reverse mapping tool</primary>
<secondary>Ant task</secondary>
</indexterm>
<para>
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>.
</para>
<para>
Following is an example of a <filename>build.xml</filename>
target that invokes the reverse mapping tool:
</para>
<example id="ref_guide_integration_revmappingtool_task">
<title>Invoking the Reverse Mapping Tool from Ant</title>
<programlisting format="linespecific">
&lt;target name="reversemap"&gt;
&lt;!-- define the reversemappingtool task; this can be done at the top of --&gt;
&lt;!-- the build.xml file, so it will be available for all targets --&gt;
&lt;taskdef name="reversemappingtool"
classname="org.apache.openjpa.jdbc.ant.ReverseMappingToolTask"/&gt;
&lt;!-- reverse map the entire database --&gt;
&lt;reversemappingtool package="com.xyz.model" directory="${basedir}/src"
customizerProperties="${basedir}/conf/reverse.properties"&gt;
&lt;codeformat tabSpaces="4" spaceBeforeParen="true" braceOnSameLine="false"/&gt;
&lt;/reversemappingtool&gt;
&lt;/target&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_integration_schematool">
<title>Schema Tool Ant Task</title>
<indexterm zone="ref_guide_integration_schematool">
<primary>Ant</primary>
<secondary>schema tool task</secondary>
</indexterm>
<indexterm zone="ref_guide_integration_schematool">
<primary>schema tool</primary>
<secondary>Ant task</secondary>
</indexterm>
<para>
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>.
</para>
<para>
Following is an example of a <filename>build.xml</filename>
target that invokes the schema tool:
</para>
<example id="ref_guide_integration_schematool_task">
<title>Invoking the Schema Tool from Ant</title>
<programlisting format="linespecific">
&lt;target name="schema"&gt;
&lt;!-- define the schematool task; this can be done at the top of --&gt;
&lt;!-- the build.xml file, so it will be available for all targets --&gt;
&lt;taskdef name="schematool" classname="org.apache.openjpa.jdbc.ant.SchemaToolTask"/&gt;
&lt;!-- add the schema components for all .schema files below the --&gt;
&lt;!-- current directory --&gt;
&lt;schematool action="add"&gt;
&lt;fileset dir="."&gt;
&lt;include name="**/*.schema" /&gt;
&lt;/fileset&gt;
&lt;/schematool&gt;
&lt;/target&gt;
</programlisting>
</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

@ -0,0 +1,28 @@
<chapter id="ref_guide_intro">
<title>Introduction</title>
<para>
OpenJPA <phrase>JPA</phrase> is a JDBC-based implementation of the JPA
standard. This document is a reference for the
configuration and use of OpenJPA <phrase>JPA</phrase>.
</para>
<section id="ref_guide_intro_audience">
<title>Intended Audience</title>
<para>
This document is intended for OpenJPA <phrase>JPA</phrase> developers. It
assumes strong knowledge of Java, familiarity with the eXtensible
Markup Language (XML), and an understanding of JPA.
If you are not familiar with JPA, please read the
<link linkend="jpa_overview_intro">JPA Overview</link>
before proceeding. We also strongly recommend taking OpenJPA's hands-on
<link linkend="tutorials">tutorials</link> to get comfortable
with OpenJPA basics.
</para>
<para>
Certain sections of this guide cover advanced topics such as
custom object-relational mapping, enterprise integration, and using
OpenJPA with third-party tools. These sections assume prior experience
with the relevant subject.
</para>
</section>
</chapter>

View File

@ -0,0 +1,439 @@
<chapter id="ref_guide_logging">
<title>Logging</title>
<indexterm zone="ref_guide_logging">
<primary>logging</primary>
</indexterm>
<indexterm zone="ref_guide_logging">
<primary>Log</primary>
</indexterm>
<para>
Logging is an important means of gaining insight into your application's
runtime behavior. OpenJPA
provides a flexible logging system that integrates with many
existing runtime systems, such as application servers and servlet
runners.
</para>
<para>
There are four built-in logging plugins: a
<link linkend="ref_guide_logging_openjpa">default logging framework</link>
that covers most needs, a <link linkend="ref_guide_logging_log4j">
Log4J</link> delegate, an <link linkend="ref_guide_logging_commons">
Apache Commons Logging</link> delegate, and a
<link linkend="ref_guide_logging_noop">no-op</link> implementation for
disabling logging.
</para>
<warning>
<para>
Logging can have a negative impact on performance. Disable
verbose logging (such as logging of SQL statements) before
running any performance tests. It is advisable to limit or
disable logging for a production system. You can
disable logging altogether by setting
the <literal>openjpa.Log</literal> property
to <literal>none</literal>.
</para>
</warning>
<section id="ref_guide_logging_channels">
<title>Logging Channels</title>
<indexterm zone="ref_guide_logging_channels">
<primary>logging</primary>
<secondary>channels</secondary>
</indexterm>
<para>
Logging is done over a number of <emphasis>logging channels</emphasis>,
each of which has a <emphasis>logging level</emphasis> which controls
the verbosity of log messages recorded for the channel. OpenJPA uses
the following logging channels:
</para>
<itemizedlist>
<listitem>
<para><literal>openjpa.Tool</literal>: Messages issued by the OpenJPA
command line and Ant tools. Most messages
are basic statements detailing which classes or files the
tools are running on. Detailed output is only available via
the logging category the tool belongs to, such as
<literal>openjpa.Enhance</literal> for the enhancer
(see <xref linkend="ref_guide_pc_enhance"/>) or
<literal>openjpa.MetaData</literal> for the mapping tool
(see <xref linkend="ref_guide_mapping_mappingtool"/>).
This logging category is provided so that you can
get a general idea of what a tool is doing without having to
manipulate logging settings that might also affect runtime
behavior.
</para>
</listitem>
<listitem>
<para><indexterm><primary>configuration</primary><secondary>log messages</secondary></indexterm><literal>openjpa.Configuration</literal>: Messages issued
by the configuration framework.
</para>
</listitem>
<listitem>
<para><indexterm><primary>enhancement</primary><secondary>log messages</secondary></indexterm><literal>openjpa.Enhance</literal>: Messages pertaining to
enhancement and runtime class generation.
</para>
</listitem>
<listitem>
<para><indexterm><primary>metadata</primary><secondary>log messages</secondary></indexterm><literal>openjpa.MetaData</literal>: Details about the generation
of metadata and object-relational mappings.
</para>
</listitem>
<listitem>
<para><literal>openjpa.Runtime</literal>: General OpenJPA runtime messages.
</para>
</listitem>
<listitem>
<para><indexterm><primary>Query</primary><secondary>log messages</secondary></indexterm><literal>openjpa.Query</literal>: Messages about queries.
Query strings and any parameter values, if applicable, will be
logged to the <literal>TRACE</literal> level at execution
time. Information about possible performance concerns
will be logged to the <literal>INFO</literal> level.
</para>
</listitem>
<listitem>
<para><indexterm><primary>remote</primary><secondary>log messages</secondary></indexterm><literal>openjpa.Remote</literal>: Remote connection and execution
messages.
</para>
</listitem>
<listitem>
<para><indexterm><primary>caching</primary><secondary>log messages</secondary></indexterm><literal>openjpa.DataCache</literal>: Messages from the L2 data
cache plugins.
</para>
</listitem>
<listitem>
<para><indexterm><primary>JDBC</primary><secondary>log messages</secondary></indexterm><literal>openjpa.jdbc.JDBC</literal>: JDBC connection information.
General JDBC information will be logged to the <literal>TRACE
</literal> level. Information about possible performance
concerns will be logged to the <literal>INFO</literal> level.
</para>
</listitem>
<listitem>
<para><indexterm><primary>SQL</primary><secondary>log messages</secondary></indexterm><literal>openjpa.jdbc.SQL</literal>: This is the most common
logging channel to use. Detailed information about the
execution of SQL statements will be sent to the
<literal>TRACE</literal> level. It is useful to enable this
channel if you are curious about the exact SQL that OpenJPA
issues to the datastore.
</para>
<para>
When using the built-in OpenJPA logging facilities, you can
enable SQL logging by adding <literal>SQL=TRACE</literal> to
your <literal>openjpa.Log</literal> property.
</para>
<para>
OpenJPA can optionally reformat the logged SQL to
make it easier to read. To enable pretty-printing,
add <literal>PrettyPrint=true</literal> to the
<link linkend="openjpa.ConnectionFactoryProperties"><literal>
openjpa.ConnectionFactoryProperties</literal></link>
property. You can control how many columns wide the
pretty-printed SQL will be with the
<literal>PrettyPrintLineLength</literal> property. The default
line length is 60 columns.</para>
<para>
While pretty printing makes things easier to read, it can make
output harder to process with tools like grep.
</para>
<para>
Pretty-printing properties configuration might look like so:
</para>
<programlisting format="linespecific">
&lt;property name="openjpa.Log" value="SQL=TRACE"/&gt;
&lt;property name="openjpa.ConnectionFactoryProperties"
value="MaxActive=100, PrettyPrint=true, PrettyPrintLineLength=72"/&gt;
</programlisting>
</listitem>
<listitem>
<para><indexterm><primary>schema</primary><secondary>log messages</secondary></indexterm><literal>openjpa.jdbc.Schema</literal>: Details about operations
on the database schema.
</para>
</listitem>
</itemizedlist>
</section>
<section id="ref_guide_logging_openjpa">
<title>OpenJPA Logging</title>
<indexterm zone="ref_guide_logging_openjpa">
<primary>logging</primary>
<secondary>default</secondary>
</indexterm>
<para>
By default, OpenJPA uses a basic logging framework with the following
output format:
</para>
<para><literal>millis</literal><literal>level</literal> [<literal>thread name</literal>] <literal>channel</literal> - <literal>message</literal></para>
<para>
For example, when loading an application that uses OpenJPA, a message
like the following will be sent to the <literal>openjpa.Runtime</literal>
channel:
</para>
<programlisting format="linespecific">
2107 INFO [main] openjpa.Runtime - Starting OpenJPA 4.0.0
</programlisting>
<para>
The default logging system accepts the following parameters:
</para>
<itemizedlist>
<listitem>
<para><literal>File</literal>: The name of the file to log to, or
<literal>stdout</literal> or <literal>stderr</literal> to send
messages to standard out and standard error, respectively.
By default, OpenJPA sends log messages to standard error.
</para>
</listitem>
<listitem>
<para><literal>DefaultLevel</literal>: The default logging level of
unconfigured channels. Recognized values are <literal>
TRACE, DEBUG, INFO, WARN,</literal> and <literal>ERROR
</literal>. Defaults to <literal>INFO</literal>.
</para>
</listitem>
<listitem>
<para><literal>DiagnosticContext</literal>: A string that will
be prepended to all log messages.
</para>
</listitem>
<listitem>
<para><literal>&lt;channel&gt;</literal>: Using the last token of
the <link linkend="ref_guide_logging_channels">logging channel
</link> name, you can configure the log level to
use for that channel. See the examples below.
</para>
</listitem>
</itemizedlist>
<example id="ref_guide_logging_openjpa_std_ex">
<title>Standard OpenJPA Log Configuration</title>
<programlisting format="linespecific">
&lt;property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO"/&gt;
</programlisting>
</example>
<example id="ref_guide_logging_openjpa_sql_ex">
<title>Standard OpenJPA Log Configuration + All SQL Statements</title>
<programlisting format="linespecific">
&lt;property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/&gt;
</programlisting>
</example>
<example id="ref_guide_logging_openjpa_file">
<title>Logging to a File</title>
<programlisting format="linespecific">
&lt;property name="openjpa.Log" value="File=/tmp/org.apache.openjpa.log, DefaultLevel=WARN, Runtime=INFO, Tool=INFO"/&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_logging_noop">
<title>Disabling Logging</title>
<indexterm zone="ref_guide_logging_noop">
<primary>logging</primary>
<secondary>disabling</secondary>
</indexterm>
<para>
Disabling logging can be useful to analyze performance without
any I/O overhead or to reduce verbosity at the console. To do
this, set the <literal>openjpa.Log</literal> property
to <literal>none</literal>.
</para>
<para>
Disabling logging permanently, however, will cause all warnings
to be consumed. We recommend using one of the
more sophisticated mechanisms described in this chapter.
</para>
</section>
<section id="ref_guide_logging_log4j">
<title>Log4J</title>
<indexterm zone="ref_guide_logging_log4j">
<primary>logging</primary>
<secondary>Log4j</secondary>
</indexterm>
<para>
When <literal>openjpa.Log</literal> is set
to <literal>log4j</literal>, OpenJPA will delegate to Log4J for logging.
In a standalone application, Log4J logging levels are
controlled by a resource named <filename>log4j.properties</filename>,
which should be available as a top-level resource (either at the top
level of a jar file, or in the root of one of
the <literal>CLASSPATH</literal> directories). When deploying to
a web or EJB application server, Log4J configuration is often
performed in a <filename>log4j.xml</filename> file instead of a
properties file. For further details on configuring Log4J,
please see the
<ulink url="http://jakarta.apache.org/log4j/docs/manual.html">Log4J
Manual</ulink>. We present an example
<filename>log4j.properties</filename> file below.
</para>
<example id="ref_guide_logging_log4j_ex">
<title>Standard Log4J Logging</title>
<programlisting format="linespecific">
log4j.rootCategory=WARN, console
log4j.category.openjpa.Tool=INFO
log4j.category.openjpa.Runtime=INFO
log4j.category.openjpa.Remote=WARN
log4j.category.openjpa.DataCache=WARN
log4j.category.openjpa.MetaData=WARN
log4j.category.openjpa.Enhance=WARN
log4j.category.openjpa.Query=WARN
log4j.category.openjpa.jdbc.SQL=WARN
log4j.category.openjpa.jdbc.JDBC=WARN
log4j.category.openjpa.jdbc.Schema=WARN
log4j.appender.console=org.apache.log4j.ConsoleAppender
</programlisting>
</example>
</section>
<section id="ref_guide_logging_commons">
<title>Apache Commons Logging</title>
<indexterm zone="ref_guide_logging_commons">
<primary>logging</primary>
<secondary>Apache Commons</secondary>
</indexterm>
<para>
Set the <literal>openjpa.Log</literal> property to <literal>commons
</literal> to use the
<ulink url="http://jakarta.apache.org/commons/logging.html">
Apache Jakarta Commons Logging</ulink> thin library for issuing
log messages. The Commons Logging libraries act as a wrapper
around a number of popular logging APIs, including the
<ulink url="http://jakarta.apache.org/log4j/docs/index.html">
Jakarta Log4J</ulink> project, and the native
<ulink url="http://java.sun.com/j2se/1.4/docs/api/java/util/logging/package-summary.html">
java.util.logging</ulink> package in JDK 1.4. If neither of these
libraries are available, then logging will fall back to using simple
console logging.
</para>
<para>
When using the Commons Logging framework in conjunction with
Log4J, configuration will be the same as was discussed in the
Log4J section above.
</para>
<section id="ref_guide_logging_jdk14">
<title>JDK 1.4 java.util.logging</title>
<indexterm zone="ref_guide_logging_jdk14">
<primary>logging</primary>
<secondary>JDK 1.4</secondary>
</indexterm>
<para>
When using JDK 1.4 or higher in conjunction with OpenJPA's
Commons Logging support, logging will proceed through Java's
built-in logging provided by the
<ulink url="http://java.sun.com/j2se/1.4/docs/api/java/util/logging/package-summary.html">
java.util.logging</ulink> package. For details on
configuring the built-in logging system, please see the
<ulink url="http://java.sun.com/j2se/1.4/docs/guide/util/logging/overview.html">
Java Logging Overview</ulink>.
</para>
<para>
By default, JDK 1.4's logging package looks in
the <filename> JAVA_HOME/lib/logging.properties</filename>
file for logging configuration. This can be overridden with
the <literal> java.util.logging.config.file</literal> system
property. For example:
</para>
<programlisting format="linespecific">
java -Djava.util.logging.config.file=mylogging.properties com.company.MyClass
</programlisting>
<example id="ref_guide_logging_jdk14_propfile">
<title>JDK 1.4 Log Properties</title>
<programlisting format="linespecific">
# specify the handlers to create in the root logger
# (all loggers are children of the root logger)
# the following creates two handlers
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler
# set the default logging level for the root logger
.level=ALL
# set the default logging level for new ConsoleHandler instances
java.util.logging.ConsoleHandler.level=INFO
# set the default logging level for new FileHandler instances
java.util.logging.FileHandler.level=ALL
# set the default formatter for new ConsoleHandler instances
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
# set the default logging level for all OpenJPA logs
openjpa.Tool.level=INFO
openjpa.Runtime.level=INFO
openjpa.Remote.level=INFO
openjpa.DataCache.level=INFO
openjpa.MetaData.level=INFO
openjpa.Enhance.level=INFO
openjpa.Query.level=INFO
openjpa.jdbc.SQL.level=INFO
openjpa.jdbc.JDBC.level=INFO
openjpa.jdbc.Schema.level=INFO
</programlisting>
</example>
</section>
</section>
<section id="ref_guide_logging_custom">
<title>Custom Log</title>
<indexterm zone="ref_guide_logging_custom">
<primary>logging</primary>
<secondary>custom</secondary>
</indexterm>
<para>
If none of available logging systems meet your needs, you can configure
the logging system with a custom logger. You might use
custom logging to integrate with a proprietary logging framework used
by some applications servers, or for logging to a graphical component
for GUI applications.
</para>
<para>
A custom logging framework must include an implementation of the
<ulink url="../apidocs/org/apache/openjpa/lib/log/LogFactory.html"><classname>org.apache.openjpa.lib.log.LogFactory</classname></ulink> interface.
We present a custom <classname>LogFactory</classname> below.
</para>
<example id="ref_guide_logging_custom_ex">
<title>Custom Logging Class</title>
<programlisting format="linespecific">
package com.xyz;
import org.apache.openjpa.lib.log.*;
public class CustomLogFactory
implements LogFactory
{
private String _prefix = "CUSTOM LOG";
public void setPrefix (String prefix)
{
_prefix = prefix;
}
public Log getLog (String channel)
{
// Return a simple extension of AbstractLog that will log
// everything to the System.err stream. Note that this is
// roughly equivalent to OpenJPA's default logging behavior.
return new AbstractLog ()
{
protected boolean isEnabled (short logLevel)
{
// log all levels
return true;
}
protected void log (short type, String message, Throwable t)
{
// just send everything to System.err
System.err.println (_prefix + ": " + type + ": "
+ message + ": " + t);
}
};
}
}</programlisting>
</example>
<para>
To make OpenJPA use your custom log factory, set the
<link linkend="openjpa.Log"><literal>openjpa.Log</literal></link>
configuration property to your factory's full class name. Because
this property is a plugin property (see
<xref linkend="ref_guide_conf_plugins"/>), you can also pass parameters
to your factory. For example, to use the example factory above and
set its prefix to "LOG MSG", you would set the
<literal>openjpa.Log</literal> property to the following string:
</para>
<programlisting format="linespecific">
com.xyz.CustomLogFactory(Prefix="LOG MSG")
</programlisting>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,976 @@
<chapter id="ref_guide_meta">
<title>Metadata</title>
<para>
The JPA Overview covers JPA metadata in
<xref linkend="jpa_overview_meta"/>.
This chapter discusses OpenJPA's extensions to standard JPA metadata.
</para>
<section id="ref_guide_meta_factory">
<title>Metadata Factory</title>
<indexterm zone="ref_guide_meta_factory">
<primary>metadata</primary>
<secondary>loading and storing</secondary>
<see>MetaDataFactory</see>
</indexterm>
<para>
The <link linkend="openjpa.MetaDataFactory"><literal>openjpa.MetaDataFactory
</literal></link> configuration property controls metadata loading and
storing. This property takes a plugin string (see
<xref linkend="ref_guide_conf_plugins"/>) describing
a concrete <ulink url="../apidocs/org/apache/openjpa/meta/MetaDataFactory.html"><classname>org.apache.openjpa.meta.MetaDataFactory</classname></ulink> implementation.
A metadata factory can load mapping information as well as persistence
metadata, or it can leave mapping information to a separate
<emphasis>mapping factory</emphasis> (see
<xref linkend="ref_guide_mapping_factory"/>).
OpenJPA recognizes the following built-in metadata factories:
</para>
<itemizedlist>
<listitem>
<para><literal>jpa</literal>: Standard JPA metadata.
This is an alias for the
<ulink url="../apidocs/org/apache/openjpa/persistence/PersistenceMetaDataFactory.html"><classname>
org.apache.openjpa.persistence.PersistenceMetaDataFactory</classname></ulink>.
</para>
</listitem>
</itemizedlist>
<para>
The standard metadata factories all accept the following properties for
locating persistent classes. Each property represents a different
mechanism for locating persistent types; you can choose the mechanism or
combination of mechanisms that are most convenient. See
<xref linkend="ref_guide_pc_pcclasses"/> for a discussion of when it
is necessary to list your persistent classes.
</para>
<itemizedlist>
<listitem>
<para><literal>Types</literal>: A semicolon-separated list of
fully-qualified persistent class names.
</para>
</listitem>
<listitem>
<para><literal>Resources</literal>: A semicolon-separated list of
resource paths to metadata files or jar archives.
Each jar archive will be scanned for
<phrase>annotated JPA entities</phrase>
.
</para>
</listitem>
<listitem>
<para><literal>URLs</literal>: A semicolon-separated list of URLs
of metadata files or jar archives.
Each jar archive will be scanned for
<phrase>annotated JPA entities</phrase>
.
</para>
</listitem>
<listitem>
<para><literal>ClasspathScan</literal>: A semicolon-separated list of
directories or jar archives listed in your classpath.
Each directory and jar archive will be scanned for
<phrase>annotated JPA entities</phrase>
.
</para>
</listitem>
</itemizedlist>
<example id="ref_guide_meta_stdfactoryex">
<title>Setting a Standard Metadata Factory</title>
<programlisting format="linespecific">
&lt;property name="openjpa.MetaDataFactory" value="jpa"/&gt;
</programlisting>
</example>
<example id="ref_guide_meta_customfactoryex">
<title>Setting a Custom Metadata Factory</title>
<programlisting format="linespecific">
&lt;property name="openjpa.MetaDataFactory" value="com.xyz.CustomMetaDataFactory"/&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_meta_ejb">
<title>Additional JPA Metadata</title>
<indexterm zone="ref_guide_meta_ejb">
<primary>metadata</primary>
<secondary>JPA additions</secondary>
</indexterm>
<para>
This section describes OpenJPA's core additions to standard entity
metadata. We present the object-relational mapping syntax to
support these additions in <xref linkend="ref_guide_mapping_ejb"/>.
Finally, <xref linkend="ref_guide_meta_ext"/> covers additional
extensions to JPA metadata that allow you to access auxiliary
OpenJPA features.
</para>
<section id="ref_guide_meta_jpa_datastoreid">
<title>Datastore Identity</title>
<indexterm zone="ref_guide_meta_jpa_datastoreid">
<primary>identity</primary>
<secondary>datastore</secondary>
</indexterm>
<para>
JPA typically requires you to declare one or more
<literal>Id</literal> fields to act as primary keys. OpenJPA, however,
can create and maintain a surrogate primary key value when you do
not declare any <literal>Id</literal> fields. This form of
persistent identity is called <emphasis>datastore
identity</emphasis>. <xref linkend="ref_guide_pc_oid"/> discusses
OpenJPA's support for datastore identity in JPA. We
cover how to map your datastore identity primary key column in
<xref linkend="ref_guide_mapping_jpa_datastoreid"/>
</para>
</section>
<section id="ref_guide_meta_jpa_version">
<title>Surrogate Version</title>
<indexterm zone="ref_guide_meta_jpa_version">
<primary>version</primary>
<secondary>surrogate</secondary>
</indexterm>
<para>
Just as OpenJPA can maintain your entity's identity without any
<literal>Id</literal> fields, OpenJPA can maintain your entity's
optimistic version without any <literal>Version</literal> fields.
<xref linkend="ref_guide_mapping_jpa_version"/> shows you how
to map surrogate version columns.
</para>
</section>
<section id="ref_guide_meta_jpa_persistent">
<title>Persistent Field Values</title>
<indexterm zone="ref_guide_meta_jpa_persistent">
<primary>persistent fields</primary>
</indexterm>
<para>
JPA defines <literal>Basic</literal>,
<literal>Lob</literal>, <literal>Embedded</literal>,
<literal>ManyToOne</literal>, and <literal>OneToOne</literal>
persistence strategies for direct field values. OpenJPA supports all
of these standard strategies, but adds one of its own:
<literal>Persistent</literal>. The
<ulink url="../apidocs/org/apache/openjpa/persistence/Persistent.html"><classname>org.apache.openjpa.persistence.Persistent</classname></ulink> metadata
annotation can represent any direct field value, including
custom types. It has the following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>FetchType fetch</literal>: Whether to load the
field eagerly or lazily. Corresponds exactly to the
same-named property of standard JPA annotations
such as <link linkend="jpa_overview_meta_basic"><classname>
Basic</classname></link>. Defaults to
<literal>FetchType.EAGER</literal>.
</para>
</listitem>
<listitem>
<para><literal>CascadeType[] cascade</literal>: Array of enum
values defining cascade behavior for this field.
Corresponds exactly to the same-named property of standard
JPA annotations such as
<link linkend="jpa_overview_meta_manytoone"><classname>
ManyToOne</classname></link>. Defaults to empty array.
</para>
</listitem>
<listitem>
<para><literal>String mappedBy</literal>: Names the field in the
related entity that maps this bidirectional relation.
Corresponds to the same-named property of standard JPA
annotations such as
<link linkend="jpa_overview_meta_onetoone"><classname>
OneToOne</classname></link>.
</para>
</listitem>
<listitem>
<para><literal>boolean optional</literal>: Whether the value can
be null. Corresponds to the same-named property of standard
JPA annotations such as
<link linkend="jpa_overview_meta_manytoone"><classname>
ManyToOne</classname></link>, but can apply to non-entity
object values as well. Defaults to <literal>true</literal>.
</para>
</listitem>
<listitem>
<para><literal>boolean embedded</literal>: Set this property to
<literal>true</literal> if the field value is stored as
an embedded object.
</para>
</listitem>
</itemizedlist>
<para>
Though you can use the <classname>Persistent</classname> annotation
in place of most of the standard direct field annotations mentioned
above, we recommend primarily using it for non-standard and custom
types for which no standard JPA annotation exists. For example,
<xref linkend="ref_guide_mapping_jpa_columns"/> demonstrates the
use of the <classname>Persistent</classname> annotation to denote
a persistent <classname>java.awt.Point</classname> field.
</para>
</section>
<section id="ref_guide_meta_jpa_persistent_coll">
<title>Persistent Collection Fields</title>
<indexterm zone="ref_guide_meta_jpa_persistent_coll">
<primary>persistent fields</primary>
<secondary>collection metadata</secondary>
</indexterm>
<para>
JPA standardizes support for collections of entities with the
<literal>OneToMany</literal> and <literal>ManyToMany</literal>
persistence strategies. OpenJPA expands collection support to handle
collections of simple types (primitive wrappers,
<classname>String</classname>s, etc), custom types, and embedded
objects.
</para>
<para>
The
<ulink url="../apidocs/org/apache/openjpa/persistence/PersistentCollection.html"><classname>org.apache.openjpa.persistence.PersistentCollection</classname></ulink>
metadata annotation represents a persistent collection field.
It has the following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>Class elementType</literal>: The class of the
collection elements. This information is usually taken
from the parameterized collection element type. You must
supply it explicitly, however, if your field isn't a
parameterized type.
</para>
</listitem>
<listitem>
<para><literal>FetchType fetch</literal>: Whether to load the
collection eagerly or lazily. Corresponds exactly to the
same-named property of standard JPA annotations
such as <link linkend="jpa_overview_meta_basic"><classname>
Basic</classname></link>. Defaults to
<literal>FetchType.LAZY</literal>.
</para>
</listitem>
<listitem>
<para><literal>String mappedBy</literal>: Names the field in the
related entity that maps this bidirectional relation.
Corresponds to the same-named property of standard JPA
annotations such as
<link linkend="jpa_overview_meta_manytomany"><classname>
ManyToMany</classname></link>.
</para>
</listitem>
<listitem>
<para><literal>CascadeType[] elementCascade</literal>: Array of
enum values defining cascade behavior for the collection
elements. Corresponds exactly to the <literal>cascade
</literal> property of standard JPA annotations
such as <link linkend="jpa_overview_meta_manytomany"><classname>ManyToMany</classname></link>. Defaults to
empty array.
</para>
</listitem>
<listitem>
<para><literal>boolean elementEmbedded</literal>: Set this
property to <literal>true</literal> if the elements are
stored as embedded objects.
</para>
</listitem>
</itemizedlist>
<para><xref linkend="ref_guide_mapping_jpa_coll"/> contains several
examples of using <classname>PersistentCollection</classname> to
mark non-standard collection fields persistent.
</para>
</section>
<section id="ref_guide_meta_jpa_persistent_map">
<title>Persistent Map Fields</title>
<indexterm zone="ref_guide_meta_jpa_persistent_map">
<primary>persistent fields</primary>
<secondary>map metadata</secondary>
</indexterm>
<para>
JPA has limited support for maps. OpenJPA introduces the
<ulink url="../apidocs/org/apache/openjpa/persistence/PersistentMap.html"><classname>org.apache.openjpa.persistence.PersistentMap</classname></ulink>
metadata annotation to represent a persistent map field.
It has the following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>Class keyType</literal>: The class of the
map keys. This information is usually taken
from the parameterized map key type. You must
supply it explicitly, however, if your field isn't a
parameterized type.
</para>
</listitem>
<listitem>
<para><literal>Class elementType</literal>: The class of the
map values. This information is usually taken
from the parameterized map value type. You must
supply it explicitly, however, if your field isn't a
parameterized type.
</para>
</listitem>
<listitem>
<para><literal>FetchType fetch</literal>: Whether to load the
collection eagerly or lazily. Corresponds exactly to the
same-named property of standard JPA annotations
such as <link linkend="jpa_overview_meta_basic"><classname>
Basic</classname></link>. Defaults to
<literal>FetchType.LAZY</literal>.
</para>
</listitem>
<listitem>
<para><literal>CascadeType[] keyCascade</literal>: Array of
enum values defining cascade behavior for the map
keys. Corresponds exactly to the <literal>cascade
</literal> property of standard JPA annotations
such as <link linkend="jpa_overview_meta_manytoone"><classname>ManyToOne</classname></link>. Defaults to
empty array.
</para>
</listitem>
<listitem>
<para><literal>CascadeType[] elementCascade</literal>: Array of
enum values defining cascade behavior for the map
values. Corresponds exactly to the <literal>cascade
</literal> property of standard JPA annotations
such as <link linkend="jpa_overview_meta_manytoone"><classname>ManyToOne</classname></link>. Defaults to
empty array.
</para>
</listitem>
<listitem>
<para><literal>boolean keyEmbedded</literal>: Set this
property to <literal>true</literal> if the map keys are
stored as embedded objects.
</para>
</listitem>
<listitem>
<para><literal>boolean elementEmbedded</literal>: Set this
property to <literal>true</literal> if the map values are
stored as embedded objects.
</para>
</listitem>
</itemizedlist>
<para>
Map keys and values in OpenJPA can be entities, simple types
(primitive wrappers, <classname>String</classname>s, etc),
custom types, or embedded objects.
<xref linkend="ref_guide_mapping_jpa_map"/> contains several
examples of using <classname>PersistentMap</classname> to annotate
persistent map fields.
</para>
</section>
</section>
<section id="ref_guide_meta_ext">
<title>Metadata Extensions</title>
<indexterm zone="ref_guide_meta_ext">
<primary>metadata</primary>
<secondary>extensions</secondary>
</indexterm>
<para>
OpenJPA extends standard metadata to allow you to access advanced OpenJPA
functionality. This section covers persistence metadata extensions; we
discuss mapping metadata extensions in
<xref linkend="ref_guide_mapping_ext"/>.
All metadata extensions are optional; OpenJPA will rely on its defaults
when no explicit data is provided.
</para>
<section id="ref_guide_meta_class">
<title>Class Extensions</title>
<para>
OpenJPA recognizes the following class extensions:
</para>
<section id="fetch-groups">
<title>Fetch Groups</title>
<indexterm zone="data-cache">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>fetch groups</tertiary>
<seealso>fetch groups</seealso>
</indexterm>
<para>
The
<ulink url="../apidocs/org/apache/openjpa/persistence/FetchGroups.html"><classname>org.apache.openjpa.persistence.FetchGroups</classname></ulink>
and <ulink url="../apidocs/org/apache/openjpa/persistence/FetchGroup.html"><classname>org.apache.openjpa.persistence.FetchGroup</classname></ulink>
annotations allow you to define fetch groups in your JPA
entities. <xref linkend="ref_guide_fetch"/> discusses OpenJPA's
support for fetch groups in general; see
<xref linkend="ref_guide_fetch_custom"/> for how to use these
annotations in particular.
</para>
</section>
<section id="data-cache">
<title>Data Cache</title>
<indexterm zone="data-cache">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>data cache</tertiary>
<seealso>caching</seealso>
</indexterm>
<para><xref linkend="ref_guide_cache"/> examines caching in OpenJPA.
Metadata extensions allow individual classes to override
system caching defaults.
</para>
<para>
OpenJPA defines the
<ulink url="../apidocs/org/apache/openjpa/persistence/DataCache.html"><classname>org.apache.openjpa.persistence.DataCache</classname></ulink>
annotation for caching information. This annotation has the
following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>boolean enabled</literal>: Whether to cache
data for instances of the class. Defaults to
<literal>true</literal> for base classes, or the
superclass value for subclasses. If you set this
property to <literal>false</literal>, all other
properties are ignored.
</para>
</listitem>
<listitem>
<para><literal>String name</literal>: Place data for instances
of the class in a named cache. By default, instance
data is placed in the same cache as superclass data, or
the default cache configured through
the <link linkend="openjpa.DataCache"><literal>
openjpa.DataCache</literal></link> configuration property
for base classes.
</para>
</listitem>
<listitem>
<para><literal>int timeout</literal>: The number of
milliseconds data for the class remains valid. Use
-1 for no timeout. Defaults to the
<link linkend="openjpa.DataCacheTimeout"><literal>
openjpa.DataCacheTimeout</literal></link> property value.
</para>
</listitem>
</itemizedlist>
<para>
The <literal>data-cache</literal> key accepts the
following values:
</para>
<itemizedlist>
<listitem>
<para><literal>true</literal>: Use the default cache, as
configured by the <link linkend="openjpa.DataCache"><literal>openjpa.DataCache</literal></link> configuration
property. This is the default when no extension is
given, unless a superclass names a different cache.
</para>
</listitem>
<listitem>
<para><literal>false</literal>: Data for instances of this
class should not be cached.
</para>
</listitem>
<listitem>
<para><literal>&lt;cache-name&gt;</literal>: Place data for
instances of this class into the cache with name
<literal>&lt;cache-name&gt;</literal>.
</para>
</listitem>
</itemizedlist>
</section>
<section id="detached-state-field">
<title>Detached State</title>
<indexterm zone="detached-state-field">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>detached state field</tertiary>
<seealso>detachment</seealso>
</indexterm>
<para>
The OpenJPA <link linkend="ref_guide_pc_enhance">enhancer</link>
may add a synthetic field to detachable classes to hold detached
state (see <xref linkend="ref_guide_detach_graph"/>
for details). You can instead declare your own detached state
field or supress the creation of a detached state field
altogether. In the latter case, your class must not use
<link linkend="ref_guide_pc_oid">datastore identity</link>,
and should declare a version field to detect optimistic
concurrency errors during detached modifications.
</para>
<para>
OpenJPA defines the
<ulink url="../apidocs/org/apache/openjpa/persistence/DetachedState.html"><classname>org.apache.openjpa.persistence.DetachedState</classname></ulink> annotation for controlling detached state. When used
to annotate a class, <classname>DetachedState</classname>
recognizes the following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>boolean enabled</literal>: Set to false to
suppress the use of detached state.
</para>
</listitem>
<listitem>
<para><literal>String fieldName</literal>: Use this property
to declare your own detached state field. The field
must be of type <classname>Object</classname>.
Typically this property is only used if the field is
inherited from a non-persisted superclass. If the field
is declared in your entity class, you will typically
annotate the field directly, as described below.
</para>
</listitem>
</itemizedlist>
<para>
If you declare your own detached state field, you can annotate
that field with <classname>DetachedState</classname> directly,
rather than placing the annotation at the class level and using
the <literal>fieldName</literal> property. When placed on a
field, <classname>DetachedState</classname> acts as a marker
annotation; it does not recognize any properties. Your
annotated field must be of type <classname>Object</classname>.
</para>
</section>
<section id="lock-groups">
<title>Lock Groups</title>
<para>
OpenJPA requires you to pre-declare subclass lock groups in the
least-derived mapped class.
<phrase>
The JPA
<ulink url="../apidocs/org/apache/openjpa/persistence/LockGroups.html"><classname>org.apache.openjpa.persistence.LockGroups</classname></ulink>
annotation accepts an array of lock group names.
</phrase>
For details on lock groups, see
<xref linkend="ref_guide_lock_groups_and_subclasses"/>.
</para>
</section>
<section id="auditable">
<title>Auditable</title>
<para>
Reserved for future use.
</para>
</section>
</section>
<section id="ref_guide_meta_field">
<title>Field Extensions</title>
<para>
OpenJPA recognizes the following field extensions:
</para>
<section id="dependent">
<title>Dependent</title>
<indexterm zone="data-cache">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>dependent</tertiary>
</indexterm>
<para>
In a <emphasis>dependent</emphasis> relation, the referenced
object is deleted whenever the owning object is deleted, or
whenever the relation is severed by nulling or resetting the
owning field. For example, if the
<literal>Magazine.coverArticle</literal> field is marked
dependent, then setting <literal>Magazine.coverArticle</literal>
to a new <classname>Article</classname> instance will
automatically delete the old <classname>Article</classname>
stored in the field. Similarly, deleting a <classname>Magazine
</classname> object will automatically delete its current cover
<classname>Article</classname>.
You can prevent an orphaned dependent object from being deleted
by assigning it to another relation in the same transaction.
</para>
<para>
OpenJPA offers a family of marker annotations to
denote dependent relations in JPA entities:
</para>
<itemizedlist>
<listitem>
<para><ulink url="../apidocs/org/apache/openjpa/persistence/Dependent.html"><classname>
org.apache.openjpa.persistence.Dependent</classname></ulink>: Marks
a direct relation as dependent.
</para>
</listitem>
<listitem>
<para><ulink url="../apidocs/org/apache/openjpa/persistence/ElementDependent.html"><classname>
org.apache.openjpa.persistence.ElementDependent</classname></ulink>:
Marks the entity elements of a collection, array, or
map field as dependent.
</para>
</listitem>
<listitem>
<para><ulink url="../apidocs/org/apache/openjpa/persistence/KeyDependent.html"><classname>
org.apache.openjpa.persistence.KeyDependent</classname></ulink>:
Marks the key entities in a map field as dependent.
</para>
</listitem>
</itemizedlist>
</section>
<section id="lrs">
<title>LRS</title>
<indexterm zone="lrs">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>lrs</tertiary>
<seealso>large result sets</seealso>
</indexterm>
<para>
This boolean extension, denoted by
<phrase>
the JPA <ulink url="../apidocs/org/apache/openjpa/persistence/LRS.html"><classname>org.apache.openjpa.persistence.LRS</classname></ulink> annotation,
</phrase>
indicates that a field should use
OpenJPA's special large result set collection or map proxies.
A complete description of large result set proxies is
available in <xref linkend="ref_guide_pc_scos_proxy_lrs"/>.
</para>
</section>
<section id="order-by">
<title>Order-By</title>
<indexterm zone="order-by">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>order-by</tertiary>
</indexterm>
<para><phrase>
The JPA Overview's
<xref linkend="jpa_overview_meta_orderby"/> describes JPA's
<literal>OrderBy</literal> annotation for loading the elements
of collection fields in a prescribed order.
</phrase>
Ordering syntax is as follows:
</para>
<programlisting format="linespecific">
#element|&lt;field name&gt;[ asc|ascending|desc|descending][, ...]
</programlisting>
<para>
The token <literal>#element</literal> represents the element
value. Simple element types such as strings and primitive
wrappers are sorted based on their natural ordering. If the
collection holds persistent objects, its elements are sorted
based on the natural ordering of the objects' primary key
values. By substituting a field name for the <literal>
#element</literal> token, you can order a collection of
persistent objects by an arbitrary field in the related type,
rather than by primary key.
</para>
<para>
The field name or <literal>#element</literal> token may be
followed by the keywords <literal>asc/ascending</literal> or
<literal>desc/descending</literal> in either all-upper or
all-lower case to mandate ascending and descending order.
If the direction is omitted, OpenJPA defaults to ascending order.
</para>
<para>
Note that the defined ordering is only applied when the
collection is loaded from the datastore. It is not maintained
by OpenJPA as you modify the collection in memory.
</para>
<para>
The following ordering string orders a collection by its
element values in descending order:
</para>
<programlisting format="linespecific">
"#element desc"
</programlisting>
<para>
The following ordering string orders a collection of
<classname>Author</classname> objects by each author's last
name in ascending order. If two last names are equal, the
authors are ordered by first name in ascending order.
</para>
<programlisting format="linespecific">
"firstName, lastName"
</programlisting>
</section>
<section id="inverse-logical">
<title>Inverse-Logical</title>
<indexterm zone="inverse-logical">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>inverse-logical</tertiary>
<seealso>bidirectional relations</seealso>
</indexterm>
<para>
This extension names the inverse field in a logical
bidirectional relation.
<phrase>
To create a logical bidrectional relation in OpenJPA, use the
<ulink url="../apidocs/org/apache/openjpa/persistence/InverseLogical.html"><classname>org.apache.openjpa.persistence.InverseLogical</classname></ulink>
annotation.
</phrase>
We discuss logical bidirectional relations and this extension
in detail in <xref linkend="ref_guide_inverses"/>.
</para>
</section>
<section id="lock-group">
<title>Lock Group</title>
<indexterm zone="lock-group">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>lock group</tertiary>
<seealso>locking</seealso>
</indexterm>
<para>
Lock groups allow for fine-grained optimistic locking
concurrency.
Use
<phrase>
OpenJPA's
<ulink url="../apidocs/org/apache/openjpa/persistence/LockGroup.html"><classname>org.apache.openjpa.persistence.LockGroup</classname></ulink>
annotation
</phrase>
to name the lock group for a field. You can exclude a field
from optimistic locking with a value of <literal>none</literal>.
We discuss lock groups and this extension further in
<xref linkend="ref_guide_lock_groups"/>.
</para>
</section>
<section id="read-only">
<title>Read-Only</title>
<indexterm zone="read-only">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>read-only</tertiary>
<seealso>persistent fields</seealso>
</indexterm>
<indexterm zone="read-only">
<primary>persistent fields</primary>
<secondary>read only</secondary>
</indexterm>
<para>
The read-only extension makes a field unwritable. The
extension only applies to existing persistent objects; new
object fields are always writeable.
</para>
<para>
To mark a field read-only in JPA metadata, set the
<ulink url="../apidocs/org/apache/openjpa/persistence/ReadOnly.html"><classname>org.apache.openjpa.persistence.ReadOnly</classname></ulink>
annotation to a
<ulink url="../apidocs/org/apache/openjpa/persistence/UpdateAction.html"><classname>org.apache.openjpa.persistence.UpdateAction</classname></ulink>
enum value. The <classname>UpdateAction</classname> enum
includes:
</para>
<itemizedlist>
<listitem>
<para><literal>UpdateAction.IGNORE</literal>: Updates to the
field are completely ignored. The field is not
considered dirty.
The new value will not even get stored in the
OpenJPA <link linkend="ref_guide_cache">data cache</link>.
</para>
</listitem>
<listitem>
<para><literal>UpdateAction.RESTRICT</literal>: Any attempt
to change the field will result in an immediate
exception.
</para>
</listitem>
</itemizedlist>
</section>
<section id="type">
<title>Type</title>
<indexterm zone="type">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>type</tertiary>
<seealso>persistent fields</seealso>
</indexterm>
<para>
OpenJPA has three levels of support for relations:
</para>
<orderedlist>
<listitem>
<para>
Relations that hold a reference to an object of a
concrete persistent class are supported by storing
the primary key values of the related instance in
the database.
</para>
</listitem>
<listitem>
<para>
Relations that hold a reference to an object of an
unknown persistent class are supported by storing
the stringified identity value of the related
instance. This level of support does not allow
queries across the relation.
</para>
</listitem>
<listitem>
<para>
Relations that hold an unknown object or interface.
The only way to support these relations is to
serialize their value to the database. This does
not allow you to query the field, and is not very
efficient.
</para>
</listitem>
</orderedlist>
<para>
Clearly, when you declare a field's type to be another
persistence-capable class, OpenJPA uses level 1 support.
By default, OpenJPA assumes that any interface-typed fields
you declare will be implemented only by other persistent
classes, and assigns interfaces level 2 support. The exception
to this rule is the <classname>java.io.Serializable</classname>
interface. If you declare a field to be of type
<classname>Serializable</classname>, OpenJPA lumps it
together with <classname>java.lang.Object</classname>
fields and other non-interface, unrecognized field types,
which are all assigned level 3 support.
</para>
<para>
With OpenJPA's type family of metadata extensions, you can
control the level of support given to your
unknown/interface-typed fields. Setting the value of this
extension to
<phrase><classname>Entity</classname></phrase>
indicates that the field value will always be some persistent
object, and gives level 2 support. Setting the value of this
extension to the class of a concrete persistent
type is even better; it gives you level 1
support (just as if you had declared your field to be
of that type in the first place). Setting this extension
to <classname>Object</classname> uses level 3
support. This is useful when you have an interface
relation that may <emphasis role="bold">not</emphasis>
hold other persistent objects (recall that OpenJPA
assumes interface fields will always hold persistent
instances by default).
</para>
<para>
This extension is also used with OpenJPA's externalization feature,
described in <xref linkend="ref_guide_pc_extern"/>.
</para>
<para>
OpenJPA defines the following type annotations for field
values, collection, array, and map elements, and map keys,
respectively:
</para>
<itemizedlist>
<listitem>
<para>
<ulink url="../apidocs/org/apache/openjpa/persistence/Type.html">
<classname>org.apache.openjpa.persistence.Type</classname>
</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="../apidocs/org/apache/openjpa/persistence/ElementType.html">
<classname>org.apache.openjpa.persistence.ElementType
</classname>
</ulink>
</para>
</listitem>
<listitem>
<para>
<ulink url="../apidocs/org/apache/openjpa/persistence/KeyType.html">
<classname>org.apache.openjpa.persistence.KeyType
</classname>
</ulink>
</para>
</listitem>
</itemizedlist>
</section>
<section id="externalizer">
<title>Externalizer</title>
<indexterm zone="externalizer">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>externalizer</tertiary>
<seealso>externalization</seealso>
</indexterm>
<para>
The
<phrase>
JPA
<ulink url="../apidocs/org/apache/openjpa/persistence/Externalizer.html"><classname>org.apache.openjpa.persistence.Externalizer</classname></ulink>
annotation
</phrase>
names a method to transform a field value into a value of
another type. See <xref linkend="ref_guide_pc_extern"/>
for details.
</para>
</section>
<section id="factory">
<title>Factory</title>
<indexterm zone="factory">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>factory</tertiary>
<seealso>externalization</seealso>
</indexterm>
<para>
The
<phrase>
JPA <ulink url="../apidocs/org/apache/openjpa/persistence/Factory.html"><classname>org.apache.openjpa.persistence.Factory</classname></ulink>
annotation
</phrase>
names a method to re-create a field value from its
externalized form. See <xref linkend="ref_guide_pc_extern"/>
for details.
</para>
</section>
<section id="external-values">
<title>External Values</title>
<indexterm zone="factory">
<primary>metadata</primary>
<secondary>extensions</secondary>
<tertiary>external values</tertiary>
<seealso>externalization</seealso>
</indexterm>
<para>
The
<phrase>
JPA
<ulink url="../apidocs/org/apache/openjpa/persistence/ExternalValues.html"><classname>org.apache.openjpa.persistence.ExternalValues</classname></ulink>
annotation
</phrase>
declares values for transformation of simple fields
to different constant values in the datastore.
See <xref linkend="ref_guide_pc_extern_values"/> for details.
</para>
</section>
</section>
<section id="ref_guide_meta_example">
<title>Example</title>
<para>
The following example shows you how to specify extensions in
metadata.
</para>
<example id="ref_guide_metaex">
<title>OpenJPA Metadata Extensions</title>
<programlisting format="linespecific">
import org.apache.openjpa.persistence.*;
@Entity
@DataCache(enabled=false)
public class Magazine
{
@ManyToMany
@LRS
@LockGroup(LockGroup.NONE)
private Collection&lt;Subscriber&gt; subscribers;
@ExternalValues({"true=1", "false=2"})
@Type(int.class)
private boolean weekly;
@PersistentCollection
@OrderBy("#element DESC")
private List&lt;String&gt; subtitles;
...
}
</programlisting>
</example>
</section>
</section>
</chapter>

View File

@ -0,0 +1,666 @@
<chapter id="ref_guide_optimization">
<title>Optimization Guidelines</title>
<indexterm zone="ref_guide_optimization">
<primary>optimization guidelines</primary>
</indexterm>
<para>
There are numerous techniques you can use in order to ensure that OpenJPA
operates in the fastest and most efficient manner. Following are some
guidelines. Each describes what impact it will have on performance and
scalability. Note that general guidelines regarding performance or
scalability issues are just that - guidelines. Depending on the
particular characteristics of your application, the optimal settings
may be considerably different than what is outlined below.
</para>
<para>
In the following table, each row is labeled with a list of
italicized keywords. These keywords identify what characteristics
the row in question may improve upon. Many of the rows are marked with
one or both of the <emphasis>performance</emphasis> and
<emphasis>scalability</emphasis> labels. It is important to bear
in mind the differences between performance and scalability (for the
most part, we are referring to system-wide scalability, and not
necessarily only scalability within a single JVM). The
performance-related hints will probably improve the performance of
your application for a given user load, whereas the
scalability-related hints will probably increase the total number of
users that your application can service. Sometimes, increasing
performance will decrease scalability, and vice versa. Typically,
options that reduce the amount of work done on the database server
will improve scalability, whereas those that push more work onto the
server will have a negative impact on scalability.
</para>
<table>
<title>Optimization Guidelines</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">Optimize database indexes</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</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.
<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 execute much faster
when the terms in the WHERE clause are appropriately
indexed. So, for a read-mostly application, appropriate
indexing will slow down updates (which are rare) but greatly
accelerate reads. This means that the system as a whole will
be faster, and also that the database will experience less
load, meaning that the system will be more scalable.
</para>
<para>
Bear in mind that over-indexing is a bad thing, both
for scalability and performance, especially for applications
that perform lots of inserts, updates, 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">JVM optimizations</emphasis>
<para>
<emphasis>performance, reliability</emphasis>
</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"/>.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">Use the data cache</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</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.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">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:
<phrase><ulink url="javadoc/openjpa/persistence/OpenJPAEntityManager.html">
OpenJPAEntityManager.setLargeTransaction</ulink></phrase>
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 month,
you can turn off population of the data cache so that
the transaction doesn't fill the entire data cache with
objects that won't be accessed again.
Again, see the Javadoc:
<phrase><ulink url="javadoc/openjpa/persistence/OpenJPAEntityManager.html">
OpenJPAEntityManager.setPopulateDataCache</ulink></phrase>
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">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.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">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>
<para>
Setting <literal>IgnoreChanges</literal> to
<literal>true</literal> will help performance, since dirty
objects can be ignored for queries, meaning that
incremental flushing or client-side processing
is not necessary. It will also improve scalability, since
overall database server usage is diminished. On the other
hand, setting <literal>IgnoreChanges</literal> to
<literal>false</literal> will have a negative impact on
scalability, even when using automatic flushing before
queries, since more operations will be performed on the
database server.
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">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.
<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 pool, then this default value
could cause undesirable pool contention.
</para>
</entry>
</row>
<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</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.
<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, it can become a factor.
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">High sequence increment</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</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.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">Use optimistic transactions</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</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.
<para>
Optimistic transactions provide the same transactional
guarantees as datastore transactions, except that you must
handle a potential optimistic verification exception at the
end of a transaction instead of assuming that a transaction
will successfully complete. In many applications, it is
unlikely that different concurrent transactions will operate
on the same set of data at the same time, so optimistic
verification increases the concurrency, and therefore both
the performance and scalability characteristics, of the
application. A common approach to handling optimistic
verification exceptions is to simply present the end user
with the fact that concurrent modifications happened, and
require that the user redo any work.
</para>
</entry>
</row>
<row>
<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.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">Always close resources</emphasis>
<para>
<emphasis>scalability</emphasis>
</para>
</entry>
<entry colname="desc">
<para>
Under certain settings, <classname>
EntityManager</classname>s, OpenJPA <classname>Extent
</classname> iterators, and <classname>Query</classname>
results may be backed by resources in the database.
</para>
<para>
For example, if you have
configured OpenJPA to use scrollable cursors and lazy object
instantiation by default, each query result will hold open
a <classname>ResultSet</classname> object, which, in turn,
will hold open a <classname>Statement</classname> object
(preventing it from being re-used). Garbage collection
will clean up these resources, so it is never necessary to
explicitly 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">Use detached state managers</emphasis>
<para>
<emphasis>performance</emphasis>
</para>
</entry>
<entry colname="desc">
<para>
Attaching and even persisting instances can be more
efficient when your detached objects use detached state
managers. By default, OpenJPA does not use detached state
managers when serializing an instance across tiers. See
<xref linkend="ref_guide_detach_graph"/> for how to force
OpenJPA to use detached state managers across tiers, and for
other options for more efficient attachment.
</para>
<para>
The downside of using a detached state manager
across tiers is that your enhanced persistent classes and
the OpenJPA libraries must be available on the client tier.
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">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.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">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.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">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.
</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.
</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></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.
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">Do not use XA transactions</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</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.
<para>
Recall that XA transactions are distinct from
managed transactions - managed transaction services
such as that provided by EJB declarative transactions
can be used both with XA and non-XA transactions. XA
transactions should only be used when a given business
transaction involves multiple different transactional
resources (an Oracle database and an IBM transactional
message queue, for example).
</para></entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">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>.
</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</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.
<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
network overhead (for the extra data) and database
processing (for any necessary additional joins) will
hurt your application's performance. If too few fields
are specified in the fetch groups, then OpenJPA will have
to make additional trips to the database to load
additional fields as necessary.
</para>
</entry>
</row>
<row>
<entry colname="name">
<emphasis role="bold">Use eager fetching</emphasis>
<para>
<emphasis>performance, scalability</emphasis>
</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.
</entry>
</row>
</tbody>
</tgroup>
</table>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,604 @@
<chapter id="ref_guide_remote">
<title>Remote and Offline Operation</title>
<indexterm zone="ref_guide_remote">
<primary>remote</primary>
</indexterm>
<indexterm>
<primary>offline</primary>
<see>remote</see>
</indexterm>
<para>
The standard JPA runtime environment is
<emphasis>local</emphasis> and <emphasis>online</emphasis>. It is
<emphasis>local</emphasis> in that components 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 client/server program designs.
</para>
<para>
OpenJPA extends the standard runtime to add <emphasis>remote</emphasis>
and <emphasis>offline</emphasis> capabilities in the form of enhanced
<link linkend="ref_guide_detach">Detach and Attach APIs</link> and
<link linkend="ref_guide_event">Remote Commit Events</link>.
The following sections explain these capabilities in detail.
</para>
<section id="ref_guide_detach">
<title>Detach and Attach</title>
<indexterm zone="ref_guide_detach">
<primary>detachment</primary>
</indexterm>
<indexterm>
<primary>attachment</primary>
<see>detachment</see>
</indexterm>
<!-- ### EJBDOC : more specific links to EM detach discussion -->
<para>
The JPA Overview describes the specification's standard
detach and attach APIs in <xref linkend="jpa_overview_em"/>.
This section enumerates OpenJPA's enhancements to the standard behavior.
</para>
<section id="ref_guide_detach_behavior">
<title>Detach Behavior</title>
<indexterm zone="ref_guide_detach_behavior">
<primary>detachment</primary>
<secondary>behavior</secondary>
</indexterm>
<para>
In JPA, objects detach automatically when they are
serialized or when a <link linkend="jpa_overview_emfactory_perscontext">persistence
context</link> ends. The specification does not define any way to
explicitly detach objects. The extended
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><classname>OpenJPAEntityManager</classname></ulink>, however, allows
you to explicitly detach objects at any time.
</para>
<programlisting format="linespecific">
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 mechanism is similar to serialization, except that only
certain fields are traversed. We will see how to control which
fields are detached in a later section.
</para>
<para><indexterm><primary>detachment</primary><secondary>of dirty objects</secondary></indexterm>
When detaching an instance that has been modified in the current
transaction (and thus made dirty), the current transaction
is flushed. This means that when subsequently re-attaching
the detached instances, OpenJPA assumes that the transaction from
which they were originally detached was committed; if
it has been rolled back, then the re-attachment process will throw
an optimistic concurrency exception.
</para>
<para>
You can stop OpenJPA from assuming the transaction will commit by
invoking <methodname>OpenJPAEntityManager.setRollbackOnly</methodname>
prior to detaching your objects. Setting the
<literal>RollbackOnly</literal> flag prevents OpenJPA from flushing
when detaching dirty objects; instead OpenJPA just runs its pre-flush
actions (see the
<methodname>OpenJPAEntityManager.preFlush</methodname>
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html">
Javadoc</ulink> for details).
</para>
<para>
This allows you to use the same
instances in multiple attach/modify/detach/rollback cycles.
Alternatively, you might also prevent a flush by making your
modifications outside of a transaction (with
<literal>NontransactionalWrite</literal> enabled) before detaching.
</para>
</section>
<section id="ref_guide_attach_behavior">
<title>Attach Behavior</title>
<indexterm zone="ref_guide_attach_behavior">
<primary>attachment</primary>
<secondary>behavior</secondary>
</indexterm>
<para>
When attaching, OpenJPA uses several strategies to determine the
optimal way to merge changes made to the detached instance. As
you will see, these strategies can even be used to attach changes
made to a transient instance which was never detached in the first
place.
</para>
<itemizedlist>
<listitem>
<para>
If the instance was detached and
<link linkend="ref_guide_detach_graph">detached state</link>
is enabled, OpenJPA will use the detached state to determine
the object's version and primary key values. In addition,
this state will tell OpenJPA which fields were loaded at the
time of detach, and in turn where to expect changes. Loaded
detached fields with null values will set the attached
instance's corresponding fields to null.
</para>
</listitem>
<listitem>
<para>
If the instance has
<phrase>
a <literal>Version</literal> field,
</phrase>
OpenJPA will consider the object detached if the version
field has a non-default value, and new otherwise.
</para>
<para>
When attaching null fields in these cases, OpenJPA cannot
distinguish between a field that was unloaded and one that
was intentionally set to null. In this case, OpenJPA will use
the current
<link linkend="ref_guide_detach_graph">detach state</link>
setting to determine how to handle null fields:
fields that would have been included in the detached state
are treated as loaded, and will in turn set the
corresponding attached field to null.
</para>
</listitem>
<listitem>
<para>
If neither of the above cases apply, OpenJPA will check to
see if an instance with the same primary key values exists
in the database. If so, the object is considered detached.
Otherwise, it is considered new.
</para>
</listitem>
</itemizedlist>
<para>
These strategies will be assigned on a per-instance basis,
such that during the attachment of an object graph more than
one of the above strategies may be used.
</para>
<para>
If you attempt to attach a versioned instance whose representation
has changed in the datastore since detachment, OpenJPA will throw an
optimistic concurrency exception upon commit or flush, just as if
a normal optimistic conflict was detected. When attaching an
instance whose database record has
been deleted since detaching, or when attaching a detached
instance into a manager that has a stale version of the object,
OpenJPA will throw an optimistic concurrency exception
from the attach method. In these cases, OpenJPA sets the
<literal>RollbackOnly</literal> flag on the transaction.
</para>
</section>
<section id="ref_guide_detach_graph">
<title>Defining the Detached Object Graph</title>
<indexterm zone="ref_guide_detach_graph">
<primary>detachment</primary>
<secondary>defining the object graph</secondary>
</indexterm>
<para>
When detached objects lose their association with the OpenJPA
runtime, they also lose the ability to load additional state
from the datastore. It is important, therefore, to populate objects
with all the persistent state you will need before detaching them.
While you are free to do this manually, OpenJPA includes
facilities for automatically populating objects when they detach.
The <link linkend="openjpa.DetachState"><literal>openjpa.DetachState
</literal></link> configuration property determines which fields
and relations are detached by default. All settings are recursive.
They are:
</para>
<orderedlist>
<listitem>
<para><literal>loaded</literal>: Detach all fields and relations
that are already loaded, but don't include unloaded fields
in the detached graph. This is the default.
</para>
</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
<link linkend="ref_guide_runtime">fetch
configuration</link>. For more information on custom
fetch groups, see <xref linkend="ref_guide_fetch"/>.
</para>
</listitem>
<listitem>
<para><literal>all</literal>: Detach all fields and relations.
Be very careful when
using this mode; if you have a highly-connected domain
model, you could end up bringing every object in the
database into memory!
</para>
</listitem>
</orderedlist>
<para>
Any field that is not included in the set determined by the detach
mode is set to its Java default value in the detached instance.
</para>
<para>
The <literal>openjpa.DetachState</literal> option is actually a
plugin string (see <xref linkend="ref_guide_conf_plugins"/>) that
allows you to also configure the following options related to
detached state:
</para>
<itemizedlist>
<listitem>
<para><literal>DetachedStateField</literal>: As described in
<xref linkend="ref_guide_attach_behavior"/> above, OpenJPA can
take advantage of a <emphasis>detached state field
</emphasis> to make the attach process more efficient.
This field is added by the enhancer and is not visible to
your application. Set this property to one of the
following values:
</para>
<itemizedlist>
<listitem>
<para><literal>transient</literal>: Use a transient
detached state field. This gives the benefits of
a detached state field to local objects that are
never serialized, but retains
serialization compatibility for client tiers without
access to the enhanced versions of your classes.
This is the default.
</para>
</listitem>
<listitem>
<para><literal>true</literal>: Use a non-transient
detached state field so that objects crossing
serialization barriers can still be attached
efficiently. This requires, however, that your
client tier have the enhanced versions of your
classes and the OpenJPA libraries.
</para>
</listitem>
<listitem>
<para><literal>false</literal>: Do not use a detached
state field.
</para>
</listitem>
</itemizedlist>
<para>
You can override the setting of this property or declare
your own detached state field on individual classes using
OpenJPA's metadata extensions. See
<xref linkend="ref_guide_detach_field"/> below.
</para>
</listitem>
<listitem>
<para><literal>DetachedStateManager</literal>: Whether to use a
detached state manager. A detached state manager makes
attachment much more efficient. Like a detached state
field, however, it breaks serialization compatibility with
the unenhanced class if it isn't transient.
</para>
<para>
This setting piggybacks on the <literal>DetachedStateField
</literal> setting above. If your detached state field is
transient, the detached state manager will also be
transient. If the detached state field is disabled, the
detached state manager will also be disabled. This is
typically what you'll want. By setting <literal>
DetachedStateField</literal> to true (or transient) and
setting this property to false, however, you can use a
detached state field <emphasis role="bold">without
</emphasis> using a detached state manager. This may be
useful for debugging or for legacy OpenJPA users who find
differences between OpenJPA's behavior with a detached state
manager and OpenJPA's older behavior without one.
</para>
</listitem>
<listitem>
<para><literal>AccessUnloaded</literal>: Whether to allow access
to unloaded fields of detached objects. Defaults to true.
Set to false to throw an exception whenever an unloaded
field is accessed. This option is only available when you
use detached state managers, as determined by the settings
above.
</para>
</listitem>
</itemizedlist>
<example id="ref_guide_detach_graph_confex">
<title>Configuring Detached State</title>
<programlisting format="linespecific">
&lt;property name="openjpa.DetachState" value="fgs(DetachedStateField=true)"/&gt;
</programlisting>
</example>
<para>
You can also alter the set of fields that will be included in the
detached graph at runtime.
<ulink url="../../api/openjpa/persistence/OpenJPAEntityManager.html"><classname>OpenJPAEntityManager</classname></ulink>s expose the
following APIs for controlling detached state:
</para>
<programlisting format="linespecific">
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);
</programlisting>
<section id="ref_guide_detach_field">
<title>Detached State Field</title>
<indexterm zone="ref_guide_detach_field">
<primary>detachment</primary>
<secondary>detached state field</secondary>
</indexterm>
<para>
When the detached state field is enabled, the OpenJPA enhancer
adds an additional field to the enhanced version of your class.
This field of type <classname>Object</classname>. OpenJPA uses
this field for bookkeeping information, such as the versioning
data needed to detect optimistic concurrency violations when the
object is re-attached.
</para>
<para>
It is possible to define this detached state field yourself.
Declaring this field in your class metadata prevents the
enhancer from adding any extra fields to the class, and keeps
the enhanced class serialization-compatible with
the unenhanced version.
The detached state field must not be persistent.
See <xref linkend="detached-state-field"/> for details on
how to declare a detached state field.
</para>
<programlisting format="linespecific">
import org.apache.openjpa.persistence.*;
@Entity
public class Magazine
implements Serializable
{
private String name;
@DetachedState private Object state;
...
}
</programlisting>
</section>
</section>
</section>
<section id="ref_guide_event">
<title>Remote Event Notification Framework</title>
<indexterm zone="ref_guide_event">
<primary>remote</primary>
<secondary>events</secondary>
</indexterm>
<indexterm>
<primary>events</primary>
<secondary>remote</secondary>
<see>remote, events</see>
</indexterm>
<para><indexterm><primary>remote</primary><secondary>events</secondary><tertiary>RemoteCommitProvider</tertiary></indexterm><indexterm><primary>remote</primary><secondary>events</secondary><tertiary>RemoteCommitListener</tertiary></indexterm>
The remote event notification framework allows a subset of the
information available through OpenJPA's transaction events (see
<xref linkend="ref_guide_runtime_pm_event"/>) to be broadcast to remote
listeners. OpenJPA's <link linkend="ref_guide_cache">data cache</link>, for
example, uses remote events to remain synchronized when deployed in
multiple JVMs.
</para>
<para>
To enable remote events, you must configure the <classname>
EntityManagerFactory</classname> to use a
<literal>RemoteCommitProvider</literal> (see below).
</para>
<para>
When a <literal>RemoteCommitProvider</literal> is properly configured, you
can register <ulink url="../apidocs/org/apache/openjpa/event/RemoteCommitListener.html"><classname>RemoteCommitListener</classname></ulink>s that will be alerted
with a list of modified object ids whenever a transaction on a remote
machine successfully commits.
</para>
<section id="ref_guide_event_conf">
<title>Remote Commit Provider Configuration</title>
<indexterm zone="ref_guide_event_conf">
<primary>remote</primary>
<secondary>events</secondary>
<tertiary>configuration</tertiary>
</indexterm>
<para>
OpenJPA includes built in remote commit providers for JMS and TCP
communication.
</para>
<section id="ref_guide_event_conf_jms">
<title>JMS</title>
<indexterm zone="ref_guide_event_conf_jms">
<primary>remote</primary>
<secondary>events</secondary>
<tertiary>JMS</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 appropriate configuration properties. The JMS
provider understands the following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>Topic</literal>: The topic that the remote commit
provider should publish notifications to and subscribe
to for notifications sent from other JVMs. Defaults to
<literal>topic/OpenJPACommitProviderTopic</literal></para>
</listitem>
<listitem>
<para><literal>TopicConnectionFactory</literal>: The JNDI name of
a <classname>javax.jms.TopicConnectionFactory</classname>
factory to use for finding topics. Defaults to <literal>
java:/ConnectionFactory</literal>. This setting may
vary depending on the application server in use; consult
the application server's documentation for details
of the default JNDI name for the
<classname>javax.jms.TopicConnectionFactory</classname>
instance. For example, under Weblogic, the JNDI name
for the TopicConnectionFactory is
<literal>javax.jms.TopicConnectionFactory</literal>.
</para>
</listitem>
<listitem>
<para><literal>ExceptionReconnectAttempts</literal>: The number of
times to attempt to reconnect if the JMS system notifies
OpenJPA of a serious connection error. Defaults to 0, meaning
OpenJPA will log the error but otherwise ignore it, hoping the
connection is still valid.
</para>
</listitem>
<listitem>
<para><literal>*</literal>: All other configuration properties
will be interpreted as settings to pass to the JNDI
<classname>InitialContext</classname> on construction. For
example, you might set the <literal>java.naming.provider.url
</literal> property to the URL of the context provider.
</para>
</listitem>
</itemizedlist>
<para>
To configure a factory to use the JMS provider, your properties
might look like the following:
</para>
<note>
<para>
Because of the nature of JMS, it is important that you invoke
<methodname>EntityManagerFactory.close</methodname>
when finished with a factory. If you do not do so, a daemon
thread will stay up in the JVM, preventing the JVM from exiting.
</para>
</note>
</section>
<section id="ref_guide_event_conf_tcp">
<title>TCP</title>
<indexterm zone="ref_guide_event_conf_tcp">
<primary>remote</primary>
<secondary>events</secondary>
<tertiary>TCP</tertiary>
</indexterm>
<para>
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")
</methodname> and a port of 1234.
</para>
<para><indexterm><primary>TCP provider</primary></indexterm>
The TCP provider can be configured by setting the <literal>
openjpa.RemoteCommitProvider</literal> plugin property to contain the
appropriate configuration settings. The TCP provider understands the
following properties:
</para>
<itemizedlist>
<listitem>
<para><literal>Port</literal>: The TCP port that the provider
should listen on for commit notifications. Defaults to
5636.
</para>
</listitem>
<listitem>
<para><literal>Addresses</literal>: A semicolon-separated list of
IP addresses to which notifications should be sent. No
default value.
</para>
</listitem>
<listitem>
<para><literal>NumBroadcastThreads</literal>: The number of
threads to create for the purpose of transmitting events to
peers. You sould increase this value as the number of
concurrent transactions increases. The maximum number of
concurrent transactions is a function of the size of the
connection pool. See the the <literal>MaxActive</literal>
property of
<literal>openjpa.ConnectionFactoryProperties</literal> in
<xref linkend="ref_guide_dbsetup_builtin"/>.
Setting a value of 0 will result in behavior where the
thread invoking <methodname>commit</methodname> will
perform the broadcast directly. Defaults to 2.
</para>
</listitem>
<listitem>
<para><literal>RecoveryTimeMillis</literal>: Amount of time to
wait in milliseconds before attempting to reconnect to a
peer of the cluster when connectivity to the peer is lost.
Defaults to 15000.
</para>
</listitem>
<listitem>
<para><literal>MaxIdle</literal>: The number of TCP sockets
(channels) to keep open to each peer in the cluster for
the transmission of events. Defaults to 2.
</para>
</listitem>
<listitem>
<para><literal>MaxActive</literal>: The maximum allowed number
of TCP sockets (channels) to open simultaneously
between each peer in the cluster.
Defaults to 2.
</para>
</listitem>
</itemizedlist>
<para>
To configure a factory to use the TCP provider, your properties
might look like the following:
</para>
<example id="ref_guide_event_conf_tcpex">
<title>TCP Remote Commit Provider Configuration</title>
<programlisting format="linespecific">
&lt;property name="openjpa.RemoteCommitProvider"
value="tcp(Addresses=10.0.1.10;10.0.1.11;10.0.1.12;10.0.1.13)"/&gt;
</programlisting>
</example>
</section>
<section id="ref_guide_event_conf_common">
<title>Common Properties</title>
<indexterm zone="ref_guide_event_conf_common">
<primary>remote</primary>
<secondary>events</secondary>
<tertiary>common properties</tertiary>
</indexterm>
<para>
In addition to the provider-specific configuration options above,
all providers accept the following plugin properties:
</para>
<itemizedlist>
<listitem>
<para><literal>TransmitPersistedObjectIds</literal>: Whether
remote commit events will include the object ids of
instances persisted in the transaction. By default only
the class names of types persisted in the transaction are
sent. This results in smaller events and more efficient
network utilization. If you have registered your own
remote commit listeners, however, you may require the
persisted object ids as well.
</para>
</listitem>
</itemizedlist>
<para>
To transmit persisted object ids in our remote commit events
using the JMS provider, we modify the previous example as follows:
</para>
</section>
</section>
<section id="ref_guide_event_customization">
<title>Customization</title>
<indexterm zone="ref_guide_event_customization">
<primary>remote</primary>
<secondary>events</secondary>
<tertiary>customization</tertiary>
</indexterm>
<para>
You can develop additional mechanisms for remote event notification be
by creating an implementation of the
<ulink url="../apidocs/org/apache/openjpa/event/RemoteCommitProvider.html"><classname>
RemoteCommitProvider</classname></ulink> interface, possibly by
extending the
<ulink url="../apidocs/org/apache/openjpa/event/AbstractRemoteCommitProvider.html"><classname>AbstractRemoteCommitProvider</classname></ulink>
abstract class. For details on particular customization needs,
contact us at <ulink url="mailto:support@solarmetric.com">
support@solarmetric.com</ulink>.
</para>
</section>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -0,0 +1,623 @@
<appendix id="supported_databases">
<title>Supported Databases</title>
<para>
Following is a table of the database and JDBC driver
versions that are supported by OpenJPA <phrase>JPA</phrase>.
<table tocentry="1"><title>Supported Databases and JDBC Drivers</title><tgroup rowsep="1" colsep="1" align="left" cols="4"><colspec colname="dbname"/><colspec colname="dbversion"/><colspec colname="drivname"/><colspec colname="drivversion"/><thead><row><entry colname="dbname">Database Name</entry><entry colname="dbversion">Database Version</entry><entry colname="drivname">JDBC Driver Name</entry><entry colname="drivversion">JDBC Driver Version</entry></row></thead><tbody><row><entry colname="dbname">Apache Derby</entry><entry colname="dbversion">10.1.2.1</entry><entry colname="drivname">Apache Derby Embedded JDBC Driver</entry><entry colname="drivversion">10.1.2.1</entry></row><row><entry colname="dbname">Borland Interbase</entry><entry colname="dbversion">7.1.0.202</entry><entry colname="drivname">Interclient</entry><entry colname="drivversion">4.5.1</entry></row><row><entry colname="dbname">Borland JDataStore</entry><entry colname="dbversion">6.0</entry><entry colname="drivname">
Borland JDataStore
</entry><entry colname="drivversion">6.0</entry></row><row><entry colname="dbname">DB2</entry><entry colname="dbversion">8.1</entry><entry colname="drivname">
IBM DB2 JDBC Universal Driver
</entry><entry colname="drivversion">1.0.581</entry></row><row><entry colname="dbname">Empress</entry><entry colname="dbversion">8.62</entry><entry colname="drivname">
Empress Category 2 JDBC Driver
</entry><entry colname="drivversion">8.62</entry></row><row><entry colname="dbname">Firebird</entry><entry colname="dbversion">1.5</entry><entry colname="drivname">JayBird JCA/JDBC driver</entry><entry colname="drivversion">1.0.1</entry></row><row><entry colname="dbname">Hypersonic Database Engine</entry><entry colname="dbversion">1.8.0</entry><entry colname="drivname">Hypersonic</entry><entry colname="drivversion">1.8.0</entry></row><row><entry colname="dbname">Informix Dynamic Server</entry><entry colname="dbversion">9.30.UC10</entry><entry colname="drivname">Informix JDBC driver</entry><entry colname="drivversion">2.21.JC2</entry></row><row><entry colname="dbname">InterSystems Cache</entry><entry colname="dbversion">5.0</entry><entry colname="drivname">Cache JDBC Driver</entry><entry colname="drivversion">5.0</entry></row><row><entry colname="dbname">Microsoft Access</entry><entry colname="dbversion">9.0 (a.k.a. "2000")</entry><entry colname="drivname">
DataDirect SequeLink
</entry><entry colname="drivversion">5.4.0038</entry></row><row><entry colname="dbname">Microsoft SQL Server</entry><entry colname="dbversion">
9.00.1399 (SQL Server 2005)
</entry><entry colname="drivname">SQLServer</entry><entry colname="drivversion">1.0.809.102</entry></row><row><entry colname="dbname">Microsoft Visual FoxPro</entry><entry colname="dbversion">7.0</entry><entry colname="drivname">
DataDirect SequeLink
</entry><entry colname="drivversion">5.4.0038</entry></row><row><entry colname="dbname">MySQL</entry><entry colname="dbversion">3.23.43-log</entry><entry colname="drivname">MySQL Driver</entry><entry colname="drivversion">3.0.14</entry></row><row><entry colname="dbname">Oracle</entry><entry colname="dbversion">8.1,9.2,10.1</entry><entry colname="drivname">Oracle JDBC driver</entry><entry colname="drivversion">10.2.0.1.0</entry></row><row><entry colname="dbname">Pointbase</entry><entry colname="dbversion">4.4</entry><entry colname="drivname">Pointbase JDBC driver</entry><entry colname="drivversion">4.4 (4.4) </entry></row><row><entry colname="dbname">PostgreSQL</entry><entry colname="dbversion">7.2.1</entry><entry colname="drivname">PostgreSQL Native Driver</entry><entry colname="drivversion">7.2 (7.2)</entry></row><row><entry colname="dbname">
Sybase Adaptive Server Enterprise
</entry><entry colname="dbversion">12.5</entry><entry colname="drivname">jConnect</entry><entry colname="drivversion">5.5 (5.5)</entry></row></tbody></tgroup></table>
</para>
<section id="dbsupport_derby">
<title>Apache Derby</title>
<example id="example_props_derby">
<title>Example properties for Derby</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: org.apache.derby.jdbc.EmbeddedDriver
openjpa.ConnectionURL: jdbc:derby:DB_NAME;create=true
</programlisting>
</example>
</section>
<section id="dbsupport_interbase">
<title>Borland Interbase</title>
<example id="example_props_interbase">
<title>Example properties for Interbase</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: interbase.interclient.Driver
openjpa.ConnectionURL: jdbc:interbase://SERVER_NAME:SERVER_PORT/DB_PATH
</programlisting>
</example>
<section id="dbsupport_interbase_issues">
<title>Known issues with Interbase</title>
<para>
<itemizedlist>
<listitem>
<para>
Interbase does not support record locking, so datastore
transactions cannot use the pessimistic lock manager.
</para>
</listitem>
<listitem>
<para>
Interbase does not support the
<literal>LOWER</literal>, <literal>SUBSTRING</literal>,
or <literal>INSTR</literal> SQL functions,
which means that
<methodname>toLowerCase()</methodname>,
<methodname>indexOf()</methodname>,
and <methodname>substring()</methodname>
methods in <phrase>JPA</phrase>QL cannot be used.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="dbsupport_jdatastore">
<title>JDataStore</title>
<example id="example_props_jdatastore">
<title>Example properties for JDataStore</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.borland.datastore.jdbc.DataStoreDriver
openjpa.ConnectionURL: jdbc:borland:dslocal:db-jdatastore.jds;create=true
</programlisting>
</example>
</section>
<section id="dbsupport_db2">
<title>IBM DB2</title>
<example id="example_props_db2">
<title>Example properties for IBM DB2</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.ibm.db2.jcc.DB2Driver
openjpa.ConnectionURL: jdbc:db2://SERVER_NAME:SERVER_PORT/DB_NAME
</programlisting>
</example>
<section id="dbsupport_db2_issues">
<title>Known issues with DB2</title>
<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>
Fields of type BLOB and CLOB are limited to 1M. This number can be
increased by extending <classname>DB2Dictionary</classname>.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="dbsupport_empress">
<title>Empress</title>
<example id="example_props_empress">
<title>Example properties for Empress</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: empress.jdbc.empressDriver
openjpa.ConnectionURL: jdbc:empress://SERVER=yourserver;PORT=6322;DATABASE=yourdb
</programlisting>
</example>
<section id="dbsupport_empress_issues">
<title>Known issues with Empress</title>
<para>
<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>
Only the category 2 non-local driver is supported.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="dbsupport_hypersonic">
<title>Hypersonic</title>
<example id="example_props_hypersonic">
<title>Example properties for Hypersonic</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: org.hsqldb.jdbcDriver
openjpa.ConnectionURL: jdbc:hsqldb:DB_NAME
</programlisting>
</example>
<section id="dbsupport_hypersonic_issues">
<title>Known issues with Hypersonic</title>
<para>
<itemizedlist>
<listitem>
<para>
Hypersonic does not properly support foreign key
constraints.
</para>
</listitem>
<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>
</section>
</section>
<section id="dbsupport_firebird">
<title>Firebird</title>
<example id="example_props_firebird">
<title>Example properties for Firebird</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: org.firebirdsql.jdbc.FBDriver
openjpa.ConnectionURL: jdbc:firebirdsql://SERVER_NAME:SERVER_PORT/DB_PATH
</programlisting>
</example>
<section id="dbsupport_firebird_issues">
<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>
Firebird does not support auto-increment columns.
</para>
</listitem>
<listitem>
<para>
Firebird does not support the
<literal>LOWER</literal>, <literal>SUBSTRING</literal>,
or <literal>INSTR</literal> SQL functions,
which means that
<methodname>toLowerCase()</methodname>,
<methodname>indexOf()</methodname>,
and <methodname>substring()</methodname>
methods in <phrase>JPA</phrase>QL cannot be used.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="dbsupport_informix">
<title>Informix</title>
<example id="example_props_informix">
<title>Example properties for Informix Dynamic Server</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.informix.jdbc.IfxDriver
openjpa.ConnectionURL: \
jdbc:informix-sqli://SERVER_NAME:SERVER_PORT/DB_NAME:INFORMIXSERVER=SERVER_ID
</programlisting>
</example>
<section id="dbsupport_informix_issues">
<title>Known issues with Informix</title>
<para>
<itemizedlist>
<listitem>
<para>
none
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="dbsupport_intersystems_cache">
<title>InterSystems Cache</title>
<example id="example_props_intersystems_cache">
<title>Example properties for InterSystems Cache</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.intersys.jdbc.CacheDriver
openjpa.ConnectionURL: jdbc:Cache://SERVER_NAME:SERVER_PORT/DB_NAME
</programlisting>
</example>
<section id="dbsupport_intersystems_cache_issues">
<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>
</section>
</section>
<section id="dbsupport_access">
<title>Microsoft Access</title>
<example id="example_props_access">
<title>Example properties for Microsoft Access</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.ddtek.jdbc.sequelink.SequeLinkDriver
openjpa.ConnectionURL: jdbc:sequelink://SERVER_NAME:SERVER_PORT
</programlisting>
</example>
<section id="dbsupport_access_issues">
<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>
</section>
</section>
<section id="dbsupport_sqlserver">
<title>Microsoft SQL Server</title>
<example id="example_props_sqlserver">
<title>Example properties for Microsoft SQLServer</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.microsoft.sqlserver.jdbc.SQLServerDriver
openjpa.ConnectionURL: \
jdbc:sqlserver://SERVER_NAME:1433;DatabaseName=DB_NAME;selectMethod=cursor;sendStringParametersAsUnicode=false
</programlisting>
</example>
<section id="dbsupport_sqlserver_issues">
<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>
The ConnectionURL must always contain the
"<literal>selectMethod=cursor</literal>" string.
</para>
</listitem>
<listitem>
<para>
Adding <literal>sendStringParametersAsUnicode=false
</literal> to the ConnectionURL may significantly
increase performance.
</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>
Floats and doubles may lose precision when stored.
</para>
</listitem>
<listitem>
<para><literal>TEXT</literal> columns cannot be used
in queries.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="dbsupport_foxpro">
<title>Microsoft FoxPro</title>
<example id="example_props_foxpro">
<title>Example properties for Microsoft FoxPro</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.ddtek.jdbc.sequelink.SequeLinkDriver
openjpa.ConnectionURL: jdbc:sequelink://SERVER_NAME:SERVER_PORT
</programlisting>
</example>
<section id="dbsupport_foxpro_issues">
<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>
</section>
</section>
<section id="dbsupport_mysql">
<title>MySQL</title>
<example id="example_props_mysql">
<title>Example properties for MySQL</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.mysql.jdbc.Driver
openjpa.ConnectionURL: jdbc:mysql://SERVER_NAME/DB_NAME
</programlisting>
</example>
<section id="dbsupport_mysql_issues">
<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>
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>
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>
Floats and doubles may lose precision when stored
in some datastores.
</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>
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>
</section>
</section>
<section id="dbsupport_oracle">
<title>Oracle</title>
<example id="example_props_oracle">
<title>Example properties for Oracle</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: oracle.jdbc.driver.OracleDriver
openjpa.ConnectionURL: jdbc:oracle:thin:@SERVER_NAME:1521:DB_NAME
</programlisting>
</example>
<section id="dbsupport_oracle_query_hints">
<title>Using Query Hints with Oracle</title>
<para>
Oracle has support for "query hints", which are formatted
comments embedded in SQL that provide some hint for
how the query should be executed. These hints are usually
designed to provide suggestions to the Oracle query
optimizer for how to efficiently perform a certainly query,
and aren't typically needed for any but the most intensive
queries.
</para>
<example id="dbsupport_oracle_query_hints_ex">
<title>Using Oracle Hints</title>
<programlisting format="linespecific">
Query query = pm.createQuery (...);
query.addExtension (org.apache.openjpa.jdbc.sql.OracleDictionary.SELECT_HINT,
"/*+ first_rows(100) */");
List results = (List) query.execute ();
</programlisting>
<programlisting format="linespecific">
Query query = em.createQuery (...);
query.setHint (org.apache.openjpa.jdbc.sql.OracleDictionary.SELECT_HINT,
"/*+ first_rows(100) */");
List results = query.getResultList ();
</programlisting>
</example>
</section>
<section id="dbsupport_oracle_issues">
<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
<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>
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>
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>
Oracle cannot store numbers with more than 38 digits
in numeric columns.
</para>
</listitem>
<listitem>
<para>
Floats and doubles may lose precision when stored.
</para>
</listitem>
<listitem>
<para>
CLOB columns cannot be used in queries.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="dbsupport_pointbase">
<title>Pointbase</title>
<example id="example_props_pointbase">
<title>Example properties for Pointbase</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.pointbase.jdbc.jdbcUniversalDriver
openjpa.ConnectionURL: \
jdbc:pointbase:DB_NAME,database.home=pointbasedb,create=true,cache.size=10000,database.pagesize=30720
</programlisting>
</example>
<section id="dbsupport_pointbase_issues">
<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>
</section>
</section>
<section id="dbsupport_postgresql">
<title>PostgreSQL</title>
<example id="example_props_postgresql">
<title>Example properties for PostgreSQL</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: org.postgresql.Driver
openjpa.ConnectionURL: jdbc:postgresql://SERVER_NAME:5432/DB_NAME
</programlisting>
</example>
<section id="dbsupport_postgresql_issues">
<title>Known issues with PostgreSQL</title>
<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>
Empty string/char values are stored as NULL.
</para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section id="dbsupport_sybase">
<title>Sybase Adaptive Server</title>
<example id="example_props_sybase">
<title>Example properties for Sybase</title>
<programlisting format="linespecific">
openjpa.ConnectionDriverName: com.sybase.jdbc2.jdbc.SybDriver
openjpa.ConnectionURL: \
jdbc:sybase:Tds:SERVER_NAME:4100/DB_NAME?ServiceName=DB_NAME&amp;BE_AS_JDBC_COMPLIANT_AS_POSSIBLE=true
</programlisting>
</example>
<section id="dbsupport_sybase_issues">
<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>
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>
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>
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>
</section>
</section>
</appendix>