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>