mirror of https://github.com/apache/openjpa.git
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:
parent
d13c9fa4f6
commit
ac98ba5c80
|
@ -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>
|
||||
|
|
|
@ -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 > 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 > 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>
|
|
@ -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>
|
|
@ -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 <T> T find (Class<T> 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 <T> T getReference (Class<T> 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>
|
|
@ -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.<property></literal>, where
|
||||
<emphasis><property></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 && 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>
|
|
@ -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
|
@ -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">
|
||||
<!ELEMENT persistence (persistence-unit*)>
|
||||
<!ELEMENT persistence-unit (description?,provider?,jta-datasource?,
|
||||
non-jta-datasource?,(class|jar-file|mapping-file)*,
|
||||
exclude-unlisted-classes?,properties?)>
|
||||
<!ATTLIST persistence-unit name CDATA #REQUIRED>
|
||||
<!ATTLIST persistence-unit transaction-type (JTA|RESOURCE_LOCAL) "JTA">
|
||||
<!ELEMENT description (#PCDATA)>
|
||||
<!ELEMENT provider (#PCDATA)>
|
||||
<!ELEMENT jta-datasource (#PCDATA)>
|
||||
<!ELEMENT non-jta-datasource (#PCDATA)>
|
||||
<!ELEMENT mapping-file (#PCDATA)>
|
||||
<!ELEMENT jar-file (#PCDATA)>
|
||||
<!ELEMENT class (#PCDATA)>
|
||||
<!ELEMENT exclude-unlisted-classes EMPTY>
|
||||
<!ELEMENT properties (property*)>
|
||||
<!ELEMENT property EMPTY>
|
||||
<!ATTLIST property name CDATA #REQUIRED>
|
||||
<!ATTLIST property value CDATA #REQUIRED>
|
||||
</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">
|
||||
<?xml version="1.0"?>
|
||||
<persistence>
|
||||
<persistence-unit name="openjpa">
|
||||
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
|
||||
<class>tutorial.Animal</class>
|
||||
<class>tutorial.Dog</class>
|
||||
<class>tutorial.Rabbit</class>
|
||||
<class>tutorial.Snake</class>
|
||||
<properties>
|
||||
<property name="openjpa.ConnectionURL" value="jdbc:hsqldb:tutorial_database"/>
|
||||
<property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/>
|
||||
<property name="openjpa.ConnectionUserName" value="sa"/>
|
||||
<property name="openjpa.ConnectionPassword" value=""/>
|
||||
<property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
</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
|
@ -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 > 5 AND PRICE < 10", Magazine.class);
|
||||
List<Magazine> 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 > ?1 AND PRICE < ?2", Magazine.class);
|
||||
|
||||
query.setParameter (1, 5d);
|
||||
query.setParameter (2, 10d);
|
||||
|
||||
List<Magazine> 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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
@ -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
|
@ -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>
|
|
@ -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 <config> Ant Tag</title>
|
||||
<programlisting format="linespecific">
|
||||
<mappingtool>
|
||||
<fileset dir="${basedir}">
|
||||
<include name="**/model/*.java" />
|
||||
</fileset>
|
||||
<config connectionUserName="scott" connectionPassword="tiger"
|
||||
connectionURL="jdbc:oracle:thin:@saturn:1521:solarsid"
|
||||
connectionDriverName="oracle.jdbc.driver.OracleDriver" />
|
||||
</mappingtool>
|
||||
</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 <config>
|
||||
Tag</title>
|
||||
<programlisting format="linespecific">
|
||||
<mappingtool>
|
||||
<fileset dir="${basedir}">
|
||||
<include name="**/model/*.java"/>
|
||||
</fileset>
|
||||
<config properties="openjpa-dev.properties"/>
|
||||
</mappingtool>
|
||||
</programlisting>
|
||||
</example>
|
||||
<example id="ref_guide_integration_propsfile">
|
||||
<title>Using the PropertiesFile Attribute of the <config>
|
||||
Tag</title>
|
||||
<programlisting format="linespecific">
|
||||
<mappingtool>
|
||||
<fileset dir="${basedir}">
|
||||
<include name="**/model/*.java"/>
|
||||
</fileset>
|
||||
<config propertiesFile="../conf/openjpa-dev.properties"/>
|
||||
</mappingtool>
|
||||
</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 <classpath> Ant Tag</title>
|
||||
<programlisting format="linespecific">
|
||||
<openjpac>
|
||||
<fileset dir="${basedir}/source">
|
||||
<include name="**/model/*.java" />
|
||||
</fileset>
|
||||
<classpath>
|
||||
<pathelement location="${basedir}/classes"/>
|
||||
<pathelement location="${basedir}/source"/>
|
||||
<pathelement path="${java.class.path}"/>
|
||||
</classpath>
|
||||
</openjpac>
|
||||
</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 <codeformat> Ant Tag</title>
|
||||
<programlisting format="linespecific">
|
||||
<reversemappingtool package="com.xyz.jdo" directory="${basedir}/src">
|
||||
<codeformat tabSpaces="4" spaceBeforeParen="true" braceOnSameLine="false"/>
|
||||
</reversemappingtool>
|
||||
</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">
|
||||
<target name="enhance">
|
||||
<!-- define the openjpac task; this can be done at the top of the -->
|
||||
<!-- build.xml file, so it will be available for all targets -->
|
||||
<taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask"/>
|
||||
|
||||
<!-- invoke enhancer on all .jdo files below the current directory -->
|
||||
<openjpac>
|
||||
<fileset dir=".">
|
||||
<include name="**/model/*.java" />
|
||||
</fileset>
|
||||
</openjpac>
|
||||
</target>
|
||||
</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">
|
||||
<target name="appids">
|
||||
<!-- define the appidtool task; this can be done at the top of -->
|
||||
<!-- the build.xml file, so it will be available for all targets -->
|
||||
<taskdef name="appidtool" classname="org.apache.openjpa.ant.ApplicationIdToolTask"/>
|
||||
|
||||
<!-- invoke tool on all .jdo files below the current directory -->
|
||||
<appidtool>
|
||||
<fileset dir=".">
|
||||
<include name="**/model/*.java" />
|
||||
</fileset>
|
||||
<codeformat spaceBeforeParen="true" braceOnSameLine="false"/>
|
||||
</appidtool>
|
||||
</target>
|
||||
</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">
|
||||
<target name="refresh">
|
||||
<!-- define the mappingtool task; this can be done at the top of -->
|
||||
<!-- the build.xml file, so it will be available for all targets -->
|
||||
<taskdef name="mappingtool" classname="org.apache.openjpa.jdbc.ant.MappingToolTask"/>
|
||||
|
||||
<!-- add the schema components for all .jdo files below the -->
|
||||
<!-- current directory -->
|
||||
<mappingtool action="buildSchema">
|
||||
<fileset dir=".">
|
||||
<include name="**/*.jdo" />
|
||||
</fileset>
|
||||
</mappingtool>
|
||||
</target>
|
||||
</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">
|
||||
<target name="reversemap">
|
||||
<!-- define the reversemappingtool task; this can be done at the top of -->
|
||||
<!-- the build.xml file, so it will be available for all targets -->
|
||||
<taskdef name="reversemappingtool"
|
||||
classname="org.apache.openjpa.jdbc.ant.ReverseMappingToolTask"/>
|
||||
|
||||
<!-- reverse map the entire database -->
|
||||
<reversemappingtool package="com.xyz.model" directory="${basedir}/src"
|
||||
customizerProperties="${basedir}/conf/reverse.properties">
|
||||
<codeformat tabSpaces="4" spaceBeforeParen="true" braceOnSameLine="false"/>
|
||||
</reversemappingtool>
|
||||
</target>
|
||||
</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">
|
||||
<target name="schema">
|
||||
<!-- define the schematool task; this can be done at the top of -->
|
||||
<!-- the build.xml file, so it will be available for all targets -->
|
||||
<taskdef name="schematool" classname="org.apache.openjpa.jdbc.ant.SchemaToolTask"/>
|
||||
|
||||
<!-- add the schema components for all .schema files below the -->
|
||||
<!-- current directory -->
|
||||
<schematool action="add">
|
||||
<fileset dir=".">
|
||||
<include name="**/*.schema" />
|
||||
</fileset>
|
||||
</schematool>
|
||||
</target>
|
||||
</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>
|
|
@ -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>
|
|
@ -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">
|
||||
<property name="openjpa.Log" value="SQL=TRACE"/>
|
||||
<property name="openjpa.ConnectionFactoryProperties"
|
||||
value="MaxActive=100, PrettyPrint=true, PrettyPrintLineLength=72"/>
|
||||
</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><channel></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">
|
||||
<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO"/>
|
||||
</programlisting>
|
||||
</example>
|
||||
<example id="ref_guide_logging_openjpa_sql_ex">
|
||||
<title>Standard OpenJPA Log Configuration + All SQL Statements</title>
|
||||
<programlisting format="linespecific">
|
||||
<property name="openjpa.Log" value="DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
|
||||
</programlisting>
|
||||
</example>
|
||||
<example id="ref_guide_logging_openjpa_file">
|
||||
<title>Logging to a File</title>
|
||||
<programlisting format="linespecific">
|
||||
<property name="openjpa.Log" value="File=/tmp/org.apache.openjpa.log, DefaultLevel=WARN, Runtime=INFO, Tool=INFO"/>
|
||||
</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
|
@ -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">
|
||||
<property name="openjpa.MetaDataFactory" value="jpa"/>
|
||||
</programlisting>
|
||||
</example>
|
||||
<example id="ref_guide_meta_customfactoryex">
|
||||
<title>Setting a Custom Metadata Factory</title>
|
||||
<programlisting format="linespecific">
|
||||
<property name="openjpa.MetaDataFactory" value="com.xyz.CustomMetaDataFactory"/>
|
||||
</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><cache-name></literal>: Place data for
|
||||
instances of this class into the cache with name
|
||||
<literal><cache-name></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|<field name>[ 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<Subscriber> subscribers;
|
||||
|
||||
@ExternalValues({"true=1", "false=2"})
|
||||
@Type(int.class)
|
||||
private boolean weekly;
|
||||
|
||||
@PersistentCollection
|
||||
@OrderBy("#element DESC")
|
||||
private List<String> subtitles;
|
||||
|
||||
...
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
|
@ -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
|
@ -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">
|
||||
<property name="openjpa.DetachState" value="fgs(DetachedStateField=true)"/>
|
||||
</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">
|
||||
<property name="openjpa.RemoteCommitProvider"
|
||||
value="tcp(Addresses=10.0.1.10;10.0.1.11;10.0.1.12;10.0.1.13)"/>
|
||||
</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
|
@ -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><property></literal> lines:
|
||||
</para>
|
||||
<programlisting format="linespecific">
|
||||
<class>samples.mixed.Machine</class>
|
||||
<class>samples.mixed.Crane</class>
|
||||
<class>samples.mixed.Bulldozer</class>
|
||||
<class>samples.mixed.Operator</class>
|
||||
</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 <create | delete> <jdo | jpa></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>
|
|
@ -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&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>
|
Loading…
Reference in New Issue