You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by mp...@apache.org on 2006/08/22 23:28:55 UTC
svn commit: r433761 [6/18] - in /incubator/openjpa/trunk/openjpa-project: ./
src/doc/manual/
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_sqlquery.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_sqlquery.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_sqlquery.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_sqlquery.xml Tue Aug 22 14:28:53 2006
@@ -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>
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_trans.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_trans.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_trans.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_trans.xml Tue Aug 22 14:28:53 2006
@@ -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>
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_why.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_why.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_why.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_overview_why.xml Tue Aug 22 14:28:53 2006
@@ -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>
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_resources.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_resources.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_resources.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_resources.xml Tue Aug 22 14:28:53 2006
@@ -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>