openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mprud...@apache.org
Subject svn commit: r433761 [7/18] - in /incubator/openjpa/trunk/openjpa-project: ./ src/doc/manual/
Date Tue, 22 Aug 2006 21:28:55 GMT
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_tutorials.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_tutorials.xml?rev=433761&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_tutorials.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/jpa_tutorials.xml Tue Aug 22 14:28:53 2006
@@ -0,0 +1,1704 @@
+
+    <chapter id="jpa_tutorials">
+      <title>JPA Tutorials</title>
+      <section id="jpa_tutorials_intro">
+        <title>OpenJPA Tutorials</title>
+        <para>
+  These tutorials provide step-by-step examples of how to use various
+  facets of the OpenJPA system. They assume a general knowledge 
+  of JPA and Java. For more information on these subjects, see
+  the following URLs:
+  </para>
+        <itemizedlist>
+          <listitem>
+            <para>
+              <ulink url="http://java.sun.com/">Sun's Java site</ulink>
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              <link linkend="jpa_overview_intro">JPA Overview Document</link>
+            </para>
+          </listitem>
+          <listitem>
+            <para>
+              <link linkend="jpa_resources">Links to JPA</link>
+            </para>
+          </listitem>
+        </itemizedlist>
+        <section id="jpa_tutorial_requirements">
+          <title>Tutorial Requirements</title>
+          <para>
+    These tutorials require that JDK 1.5 or greater be installed
+    on your computer, and that <literal>java</literal> and 
+    <literal>javac</literal> are in your <literal>PATH</literal> when 
+    you open a command shell.
+    </para>
+        </section>
+      </section>
+      <section id="jpa_tutorial">
+        <title>OpenJPA Tutorial</title>
+        <para>
+  In this tutorial you will become familiar with the basic tools and 
+  development processes under OpenJPA by creating a simple JPA application.
+  </para>
+        <section id="jpa_tutorial_chapter1">
+          <title>The Pet Shop</title>
+          <para>
+    Imagine that you have decided to create a software toolkit to be used 
+    by pet shop operators. This toolkit must provide a number of solutions 
+    to common problems encountered at pet shops. Industry analysts indicate
+    that the three most desired features are inventory maintenance, 
+    inventory growth simulation, and behavioral analysis. Not one to 
+    question the sage advice of experts, you choose to attack these three
+    problems first.
+    </para>
+          <para>
+    According to the aforementioned experts, most pet shops focus on three 
+    types of animals only: dogs, rabbits, and snakes. This ontology 
+    suggests the following class hierarchy:
+    </para>
+          <para>
+            <screen format="linespecific">
+                       Animal
+                         ^
+                         |
+               +--------------------+
+               |         |          |
+              Dog      Rabbit     Snake
+         </screen>
+          </para>
+          <section id="jpa_tutorial_files">
+            <title>Included Files</title>
+            <para>
+      We have provided an implementation of <classname>Animal</classname>
+      and <classname>Dog</classname> classes, plus some helper classes 
+      and files to create the initial schema and populate the database 
+      with some sample dogs. Let's take a closer look at these classes.
+      </para>
+            <itemizedlist>
+              <listitem>
+                <para><ulink url="../../../tutorial/persistence/AnimalMaintenance.java"><classname>
+          tutorial.persistence.AnimalMaintenance</classname></ulink>:
+          Provides some utility methods for examining and 
+          manipulating the animals stored in the database. We will
+          fill in method definitions in 
+          <xref linkend="jpa_tutorial_chapter3"/>.
+          </para>
+              </listitem>
+              <listitem>
+                <para><ulink url="../../../tutorial/persistence/Animal.java"><classname>tutorial.persistence.Animal</classname></ulink>:
+          This is the superclass of all animals that this pet store 
+          software can handle.
+          </para>
+              </listitem>
+              <listitem>
+                <para><ulink url="../../../tutorial/persistence/Dog.java"><classname>tutorial.persistence.Dog</classname></ulink>: 
+          Contains data and methods specific to dogs.
+          </para>
+              </listitem>
+              <listitem>
+                <para><ulink url="../../../tutorial/persistence/Rabbit.java"><classname>tutorial.persistence.Rabbit</classname></ulink>: 
+          Contains data and 
+          methods specific to rabbits. It will be used in 
+          <xref linkend="jpa_tutorial_chapter4"/>.
+          </para>
+              </listitem>
+              <listitem>
+                <para><ulink url="../../../tutorial/persistence/Snake.java"><classname>tutorial.persistence.Snake</classname></ulink>: 
+          Contains data and 
+          methods specific to snakes. It will be used in 
+          <xref linkend="jpa_tutorial_chapter5"/>.
+          </para>
+              </listitem>
+              <listitem>
+                <para><ulink url="../../../META-INF/persistence.xml"><filename>../../META-INF/persistence.xml</filename></ulink>:
+          This XML file contains OpenJPA-specific and standard JPA 
+          configuration settings.
+          </para>
+                <para>
+          It is important to load all persistent entity classes at
+          startup so that OpenJPA can match database discriminator values
+          to entity classes.  Often this happens automatically.  
+          Some parts of this tutorial, however, do require that all 
+          entity classes be loaded explicitly.  The JPA
+          standard includes persistent class listings in its XML
+          configuration format.  Add the following lines to <filename>
+          ../../META-INF/persistence.xml</filename> between the
+          <literal>&lt;provider&gt;</literal> and the
+          <literal>&lt;properties&gt;</literal> elements:
+          </para>
+                <programlisting format="linespecific">
+&lt;class&gt;tutorial.persistence.Animal&lt;/class&gt;
+&lt;class&gt;tutorial.persistence.Dog&lt;/class&gt;
+</programlisting>
+              </listitem>
+              <listitem>
+                <para><ulink url="../../../tutorial/persistence/solutions"><filename>solutions</filename></ulink>: The solutions 
+          directory contains the complete solutions to this tutorial,
+          including finished versions of the
+          <filename>.java</filename> files listed above.
+          </para>
+              </listitem>
+            </itemizedlist>
+          </section>
+          <section id="jpa_tutorial_utilities">
+            <title>Important Utilities</title>
+            <itemizedlist>
+              <listitem>
+                <para><command>java</command>: Runs main methods in specified 
+          Java classes.
+          </para>
+              </listitem>
+              <listitem>
+                <para><command>javac</command>: Compiles <filename>.java
+          </filename> files into <filename>.class</filename> 
+          files that can be executed by <command>java</command>.
+          </para>
+              </listitem>
+              <listitem>
+                <para><indexterm><primary>openjpac</primary></indexterm><command>openjpac</command>:
+          Runs the OpenJPA enhancer against the specified
+          classes. More information is available in
+          <xref linkend="ref_guide_pc_enhance"/> of the Reference 
+          Guide.
+          </para>
+              </listitem>
+              <listitem>
+                <para><indexterm><primary>mappingtool</primary></indexterm><command>mappingtool</command>: A 
+          utility that can be used to create and maintain the 
+          object-relational mappings and schema of all persistent
+          classes in a JDBC-compliant datastore.  This functionality 
+          allows the underlying mappings and schema to be easily 
+          kept up-to-date with the Java classes in the system. See 
+          <xref linkend="ref_guide_mapping"/>
+          of the Reference Guide for more information.
+          </para>
+              </listitem>
+            </itemizedlist>
+          </section>
+        </section>
+        <section id="jpa_tutorial_chapter2">
+          <title>Getting Started</title>
+          <para>
+    Let's compile the initial classes and see them in action. To do
+    so, we must compile the <filename>.java</filename> files, as we would 
+    with any Java project, and then pass the resulting classes through
+    the OpenJPA enhancer:
+    </para>
+          <note>
+            <para><indexterm><primary>CLASSPATH</primary></indexterm>
+      Be sure that your <envar>CLASSPATH</envar> is set correctly. 
+      Note that your OpenJPA
+      install directory should be in the <envar>CLASSPATH</envar>, as
+      the tutorial classes are located in the <literal>
+      tutorial/persistence</literal> directory under your OpenJPA install 
+      directory, and are in the <literal>tutorial.persistence</literal> 
+      package.
+      </para>
+          </note>
+          <orderedlist>
+            <listitem>
+              <para>
+        Make sure you are in the <filename>
+        tutorial/persistence</filename> 
+        directory.  All examples throughout the tutorial assume that
+        you are in this directory.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        Examine <filename>Animal.java</filename>,
+        <filename>Dog.java</filename>, and
+        <filename>SeedDatabase.java</filename>
+        </para>
+              <para>
+        These files are good examples of the simplicity JPA
+        engenders.  As noted earlier, persisting an object or 
+        manipulating an object's persistent data requires almost no 
+        JPA-specific code.
+        For a very simple example of creating persistent objects,
+        please see the <literal>seed</literal> method of
+        <filename>SeedDatabase.java</filename>. Note the objects are
+        created with normal Java 
+        constructors. The files <filename>Animal.java</filename> and
+        <filename>Dog.java</filename> are also good examples of
+        how JPA allows you to manipulate persistent data 
+        without writing any specific JPA code, by providing
+        simple annotations.
+        </para>
+              <para>
+        Let's take a look at the <filename>Animal.java</filename> file.
+        Notice that the class is a Plain Old Java Object (POJO), with
+        several annotations describing how the class is mapped into
+        a relational database.  First, let's examine the class level
+        annotations:
+        </para>
+              <programlisting format="linespecific">
+@Entity(name="Animal")
+@Table(name="JPA_TUT_ANIMAL")
+@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name="SPECIES", length=100)
+public abstract class Animal
+{
+    ...
+}
+</programlisting>
+              <para>
+        The annotations serve to map the class into the database.  For
+        more information on these and other annotations, see
+        <xref linkend="jpa_overview_meta"/> and
+        <xref linkend="jpa_overview_mapping"/>.
+        </para>
+              <orderedlist>
+                <listitem>
+                  <para><command>@Entity</command>: This annotation indicates
+            that instances of this class may be persistent entities.
+            The value of the <command>name</command> attribute is
+            the entity name, and is used in queries, etc.
+            </para>
+                </listitem>
+                <listitem>
+                  <para><command>@Table</command>: This annotation is used
+            to map the entity to a primary table.  The value of the
+            <command>name</command> attribute specifies the name
+            of the relational table to use as the primary table.
+            </para>
+                </listitem>
+                <listitem>
+                  <para><command>@Inheritance</command>: When multiple classes
+            in an inheritance hierarchy are persistent entity types,
+            it is important to describe how the inheritance
+            hierarchy is mapped.  Setting the value of the
+            <command>strategy</command> attribute to
+            <command>InheritanceType.SINGLE_TABLE</command>
+            indicates that the primary table for all subclasses
+            shall be the same table as for the superclass.
+            </para>
+                </listitem>
+                <listitem>
+                  <para><command>@DiscriminatorColumn</command>: With a
+            <command>SINGLE_TABLE</command> inheritance mapping
+            strategy, instances of multiple classes will be stored
+            in the same table.  This annotation describes a column
+            in that table that is used to determine the type of
+            an instance whose data is stored in a particular row.
+            The <command>name</command> attribute is the name of
+            the column, and the <command>length</command> attribute
+            indicates the size of the column.  By default, the
+            unqualified class name for the instance is stored
+            in the discriminator column.  To store a different
+            value for a type, use the <command>@DiscriminatorValue
+            </command> annotation.
+            </para>
+                </listitem>
+              </orderedlist>
+              <para>
+        Let's take a look at our class' field annotations.
+        We have chosen to use <emphasis>field access</emphasis> for
+        our entities, meaning the persistence implementation will 
+        get and set persistent state directly through our class'
+        declared fields.  We could have chosen to use <emphasis>
+        property access</emphasis>, in which the implementation 
+        accesses persistent state through our JavaBean getter and
+        setter methods.  In that case, we would have annotated our
+        getter methods rather than our fields.
+        </para>
+              <programlisting format="linespecific">
+@Id
+@GeneratedValue
+@Column(name="ID")
+private long id;
+
+@Basic @Column(name="ANIMAL_NAME")
+private String name = null;
+
+@Basic @Column(name="COST")
+private float price = 0f;
+</programlisting>
+              <para>
+        The annotations serve to map the fields into the database.  For
+        more information on these and other annotations, see
+        <xref linkend="jpa_overview_meta"/>.
+        </para>
+              <orderedlist>
+                <listitem>
+                  <para><command>@Id</command>: This annotation indicates that
+            the field is to be mapped to a primary key column in
+            the database.  
+            </para>
+                </listitem>
+                <listitem>
+                  <para><command>@GeneratedValue</command>:
+            Indicates that the implementation will generate a 
+            value for the field automatically.
+            </para>
+                </listitem>
+                <listitem>
+                  <para><command>@Column</command>: This annotation describes
+            the column to which the field will be mapped.  The
+            <command>name</command> attribute specifies the name
+            of the column.
+            </para>
+                </listitem>
+                <listitem>
+                  <para><command>@Basic</command>: This annotation indicates
+            that the field is simply mapped into a column.  There
+            are other annotations that indicate entity
+            relationships and other more complex mappings.
+            </para>
+                </listitem>
+              </orderedlist>
+            </listitem>
+            <listitem>
+              <para>Compile the <filename>.java</filename> files.</para>
+              <programlisting format="linespecific">
+javac *.java
+</programlisting>
+              <para>
+        You can use any java compiler instead of 
+        <command>javac</command>.
+        </para>
+            </listitem>
+            <listitem>
+              <para>Enhance the persistent classes.</para>
+              <programlisting format="linespecific">
+openjpac -p persistence.xml Animal.java Dog.java
+</programlisting>
+              <para>
+        This step runs the OpenJPA enhancer on the 
+        <filename>Animal.java</filename> and
+        <filename>Dog.java</filename> files mentioned above.
+        See <xref linkend="ref_guide_pc_enhance"/> of the Reference 
+        Guide for more information on the enhancer, including how to
+        use automatic runtime enhancement.
+        </para>
+              <note>
+                <para>
+          The <literal>-p</literal> flag points the enhancer to your
+          <filename>persistence.xml</filename> configuration file.
+          All OpenJPA tools look for default configuration in a
+          resource called <filename>openjpa.xml</filename> or
+          <filename>META-INF/openjpa.xml</filename>.  Thus you
+          can avoid passing the <literal>-p</literal> argument to
+          tools by using this configuration file name in place of
+          <filename>persistence.xml</filename>.  See
+          <xref linkend="ref_guide_conf"/> in the Reference Guide
+          for details on OpenJPA configuration.
+          </para>
+              </note>
+            </listitem>
+          </orderedlist>
+          <section id="jpa_tutorial_chapter2_datastore">
+            <title>Configuring the Datastore</title>
+            <para>
+      Now that we've compiled the source files and enhanced the
+      persistent classes, we're ready to set up the database. 
+      <ulink url="http://hsqldb.sourceforge.net">Hypersonic SQL</ulink>,
+      a pure Java relational database, is included in the OpenJPA 
+      distribution. 
+      We have included this database because it is simple to set up and 
+      has a small memory footprint; however, you can use this tutorial 
+      with any of the relational databases that we support.  You can also
+      write your own plugin for any database that we do not support. For 
+      the sake of simplicity, this tutorial only describes how to set up
+      connectivity to a Hypersonic SQL database. For more
+      information on how to connect to a different database or
+      how to add support for other databases, see
+      <xref linkend="ref_guide_dbsetup"/> of the 
+      Reference Guide.
+      </para>
+            <orderedlist>
+              <listitem>
+                <para><indexterm><primary>mappingtool</primary></indexterm>
+          Create the object-relational mappings and database schema.
+          </para>
+                <programlisting format="linespecific">
+mappingtool -p persistence.xml Animal.java Dog.java
+</programlisting>
+                <para>
+          This command propagates the necessary schema for the
+          specified classes to the database configured in 
+          <filename>persistence.xml</filename>.  If you are 
+          using the default Hypersonic SQL setup, the first time you 
+          run the mapping tool Hypersonic will create
+          <filename>tutorial_database.properties</filename> and
+          <filename>tutorial_database.script</filename> database
+          files in your current directory.  To 
+          delete the database, just delete these files.
+          </para>
+                <para>
+          By default, JPA uses object-relational mapping
+          information stored in annotations in your source files.
+          <xref linkend="jpa_overview_mapping"/> of the
+          JPA Overview will help you understand mapping
+          annotations.
+          Additionally, <xref linkend="ref_guide_mapping"/> of the 
+          Reference Guide describes your other mapping options in 
+          detail.
+          </para>
+                <para>
+          </para>
+                <para>
+          If you are curious, you can view the schema OpenJPA 
+          created for the tutorial classes with OpenJPA's schema tool: 
+          </para>
+                <programlisting format="linespecific">
+schematool -p persistence.xml -a reflect -f tmp.schema
+</programlisting>
+                <para>
+          This will create a <filename>tmp.schema</filename> file
+          with an XML representation of the database schema.  The
+          XML should be self explanatory; see
+          <xref linkend="ref_guide_schema_xml"/>
+          of the Reference Guide for details.  You may delete the
+          <filename>tmp.schema</filename> file before proceeding.
+          </para>
+              </listitem>
+              <listitem>
+                <para>Populate the database with sample data.</para>
+                <programlisting format="linespecific">
+java tutorial.persistence.SeedDatabase
+</programlisting>
+              </listitem>
+            </orderedlist>
+            <para>
+      Congratulations! You have now created an JPA-accessible
+      persistent store, and seeded it with some sample data.
+      </para>
+          </section>
+        </section>
+        <section id="jpa_tutorial_chapter3">
+          <title>Inventory Maintenance</title>
+          <para>
+    The most important element of a successful pet store product, say the 
+    experts, is an inventory maintenance mechanism. So, let's work on the 
+    <classname>Animal</classname> and <classname>Dog</classname> classes a
+    bit to permit user interaction with the database.
+    </para>
+          <para>
+    This chapter should familiarize you with some of the basics of the 
+    <ulink url="../../ejb-3_0-pr-spec-persistence.pdf">JPA 
+    specification</ulink> and the mechanics of compiling and enhancing 
+    persistent classes. You will also become familiar with the mapping 
+    tool for propagating the persistent schema into the database.
+    </para>
+          <para>
+    First, let's add some code to
+    <filename>AnimalMaintenance.java</filename> that allows us to examine
+    the animals currently in the database. 
+    </para>
+          <orderedlist>
+            <listitem>
+              <para>
+        Add code to <filename>AnimalMaintenance.java</filename>.
+        </para>
+              <para>
+        Modify the <methodname>getAnimals</methodname> method of 
+        <filename>AnimalMaintenance.java</filename> to look like this:
+        </para>
+              <programlisting format="linespecific">
+    /**
+     *  Return a list of animals that match the specified query filter.
+     *
+     *  @param  filter      the JPQL filter to apply to the query
+     *  @param  cls         the class of animal to query on
+     *  @param  em          the EntityManager to obtain the query from
+     */
+    public static List getAnimals (String filter, EntityManager em)
+    {
+        // Execute a query for the specified filter.
+        Query query = em.createQuery (filter);
+        return query.getResultList ();
+    }
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>
+        Compile <filename>AnimalMaintenance.java</filename>.
+        </para>
+              <programlisting format="linespecific">
+javac AnimalMaintenance.java
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>Take a look at the animals in the database.</para>
+              <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance list Animal
+</programlisting>
+              <para>
+        Notice that <methodname>list</methodname> optionally takes a
+        query filter. Let's explore the database some more, this time 
+        using filters:
+        </para>
+              <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance list "select a from Animal a where a.name = 'Binney'"
+java tutorial.persistence.AnimalMaintenance list "select a from Animal a where a.price &lt;= 50"
+</programlisting>
+              <para>
+        The Java Persistence Query Language (JPQL) is designed to look 
+        and behave much like an object oriented SQL dialect. The
+        <literal>name</literal> and <literal>price</literal> fields
+        identified in the above queries map to the member fields of
+        those names in <classname>
+        tutorial.persistence.Animal</classname>.  
+        More details on JPQL syntax is available in
+        <xref linkend="jpa_overview_query"/> of the JPA Overview.  
+        </para>
+            </listitem>
+          </orderedlist>
+          <para>
+    Great! Now that we can see the contents of the database,
+    let's add some code that lets us add and remove animals.
+    </para>
+          <section id="jpa_tutorial_chapter3_persist">
+            <title>Persisting Objects</title>
+            <para>
+      As new dogs are born or acquired, the store owner will
+      need to add new records to the inventory database. In this
+      section, we'll write the code to handle additions through
+      the <classname>tutorial.persistence.AnimalMaintenance</classname> 
+      class.
+      </para>
+            <para>
+      This section will familiarize you with the mechanism for
+      storing persistent instances in a JPA entity
+      manager. We will create a new dog, obtain a
+      <classname>Transaction</classname> from a 
+      <classname>EntityManager</classname>, and, within the 
+      transaction, make the new dog object persistent.
+      </para>
+            <para><classname>tutorial.persistence.AnimalMaintenance</classname> 
+      provides a reflection-based facility for creating any type of 
+      animal, provided that the animal has a two-argument constructor
+      whose first argument corresponds to the name of the animal
+      and whose second argument is an implementation-specific 
+      primitive. This reflection-based system is in place to keep this 
+      tutorial short and remove repetitive creation mechanisms. It is 
+      not a required part of the JPA specification.
+      </para>
+            <orderedlist>
+              <listitem>
+                <para>Add the following code to <filename>
+          AnimalMaintenance.java</filename>.
+          </para>
+                <para>
+          Modify the <methodname>persistObject</methodname> method of 
+          <filename>AnimalMaintenance.java</filename> to look like 
+          this:
+          </para>
+                <programlisting format="linespecific">
+    /**
+     *  Performs the actual JPA work of putting &lt;code&gt;object&lt;/code&gt;
+     *  into the data store.
+     *
+     *  @param  object  the object to persist in the data store
+     */
+    public static void persistObject (EntityManager em, Object object)
+    {
+        // Mark the beginning of the unit of work boundary.
+        em.getTransaction ().begin ();
+
+        em.persist (object);
+
+        // Mark the end of the unit of work boundary,
+        // and record all inserts in the database.
+        em.getTransaction ().commit ();
+        System.out.println ("Added " + object);
+    }
+</programlisting>
+                <note>
+                  <para>In the above code, we pass in an
+          <classname>EntityManager</classname>.
+          <classname>EntityManager</classname>s may be either
+          container managed or application managed.  In this tutorial,
+          because we're operating outside a container, we're using
+          application managed <classname>EntityManager</classname>s.
+          In managed environments,
+          <classname>EntityManager</classname>s are typically
+          container managed, and thus injected or looked up via JNDI.
+          Application managed <classname>EntityManager</classname>s
+          can be used in both managed and unmanaged environments, and
+          are created by an
+          <classname>EntityManagerFactory</classname>.  An
+          <classname>EntityManagerFactory</classname> can be obtained
+          from the
+          <classname>javax.persistence.Persistence</classname> class.
+          This class provides some convenience methods for
+          obtaining an <classname>EntityManagerFactory</classname>.
+          </para>
+                </note>
+              </listitem>
+              <listitem>
+                <para>
+          Recompile <filename>AnimalMaintenance.java</filename>.
+          </para>
+                <programlisting format="linespecific">
+javac AnimalMaintenance.java
+</programlisting>
+              </listitem>
+            </orderedlist>
+            <para>
+      You now have a mechanism for adding new dogs to the database. Go 
+      ahead and add some by running
+      <command>java tutorial.persistence.AnimalMaintenance add Dog &lt;name&gt; &lt;price&gt;</command> 
+      For example:
+      </para>
+            <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance add Dog Fluffy 35
+</programlisting>
+            <para>
+      You can view the contents of the database with:
+      </para>
+            <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance list Dog
+</programlisting>
+          </section>
+          <section id="jpa_tutorial_chapter3_delete">
+            <title>Deleting Objects</title>
+            <para>
+      What if someone decides to buy one of the dogs? The store owner 
+      will need to remove that animal from the database, since it is no 
+      longer in the inventory. 
+      </para>
+            <para>
+      This section demonstrates how to remove data from the datastore.
+      </para>
+            <orderedlist>
+              <listitem>
+                <para>
+          Add the following code to <filename>AnimalMaintenance.java
+          </filename>.
+          </para>
+                <para>
+          Modify the <methodname>deleteObjects</methodname> method of 
+          <filename>AnimalMaintenance.java</filename> to look like 
+          this:
+          </para>
+                <programlisting format="linespecific">
+    /**
+     *  Performs the actual JPA work of removing 
+     *  &lt;code&gt;objects&lt;/code&gt; from the datastore.
+     *
+     *  @param  objects     the objects to persist in the datastore
+     *  @param  em          the EntityManager to delete with
+     */
+    public static void deleteObjects (Collection objects, EntityManager em)
+    {
+        // Mark the beginning of the unit of work boundary.
+        em.getTransaction ().begin ();
+
+        // This method removes the objects in 'objects' from the data store.
+        for (Object ob : objects)
+        {
+            System.out.println ("Removed animal: " + ob);
+            em.remove (ob);
+        }
+
+        // Mark the end of the unit of work boundary, and record all
+        // deletes in the database.
+        em.getTransaction ().commit ();
+    }
+</programlisting>
+              </listitem>
+              <listitem>
+                <para>
+          Recompile <filename>AnimalMaintenance.java</filename>.
+          </para>
+                <programlisting format="linespecific">
+javac AnimalMaintenance.java
+</programlisting>
+              </listitem>
+              <listitem>
+                <para>Remove some animals from the database.</para>
+                <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance remove &lt;query&gt;
+</programlisting>
+                <para>
+          Where <replaceable>&lt;query&gt;</replaceable> is a query 
+          string like those used for listing animals above.
+          </para>
+              </listitem>
+            </orderedlist>
+            <para>
+      All right. We now have a basic pet shop inventory
+      management system. From this base, we will add some of the
+      more advanced features suggested by our industry experts.
+      </para>
+          </section>
+        </section>
+        <section id="jpa_tutorial_chapter4">
+          <title>Inventory Growth</title>
+          <para>
+    Now that we have the basic pet store framework in place, let's add 
+    support for the next pet in our list: the rabbit. The rabbit is a bit 
+    different than the dog; pet stores sell them all for the same price, 
+    but gender is critically important since rabbits reproduce rather 
+    easily and quickly. Let's put together a class representing a rabbit.
+    </para>
+          <para>
+    In this chapter, you will see some more queries and write a 
+    bidirectional relation between objects.
+    </para>
+          <para>
+    Provided with this tutorial is a file called 
+    <filename>Rabbit.java</filename> which contains a sample 
+    <classname>Rabbit</classname> implementation. 
+    </para>
+          <orderedlist>
+            <listitem>
+              <para>
+        Examine <filename>Rabbit.java</filename>.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        The Rabbit class above contains a bidirectional 
+        relationship between parents and children. From the Java side 
+        of things, a bidirectional relationship is simply a
+        pair of fields that are conceptually linked. There is no 
+        special Java work necessary to express bidirectionality. 
+        However, you must identify the relationship as bidirectional
+        using JPA <link linkend="jpa_overview_meta">
+        annotations</link> so the mapping tool can create the most 
+        efficient schema.
+        </para>
+              <para>
+        Insert this snippet of code immediately
+        <emphasis>before</emphasis> the <literal>children</literal>
+        field declaration in the <filename>Rabbit.java</filename> file.
+        </para>
+              <programlisting format="linespecific">
+    @ManyToMany
+    @JoinTable(name="RABBIT_CHILDREN",
+        joinColumns=@JoinColumn(name="PARENT_ID"),
+        inverseJoinColumns=@JoinColumn(name="CHILD_ID"))
+</programlisting>
+              <para>
+        The <literal>@ManyToMany</literal> annotation indicates that
+        <literal>children</literal> is one side of a many-to-many 
+        relation.  <literal>@JoinTable</literal> describes how this 
+        relation maps to a database join table.  The annotation's 
+        <literal>joinColumns</literal> name the join table's foreign 
+        key columns linking to the owning instance (the parent).  In 
+        this case, column <literal>RABBIT_CHILDREN.PARENT_ID</literal> 
+        is a foreign key to the parent's <literal>ID</literal> primary 
+        key column.  Similarly, the <literal>inverseJoinColumns
+        </literal> attribute denotes the foreign key columns linking to
+        the collection elements (the children).
+        For more details on the <literal>@JoinTable</literal>
+        annotation, see <xref linkend="jpa_overview_mapping"/> of the 
+        JPA Overview.  
+        </para>
+              <para>
+        Now we'll map the other side of this bidirectional relation,
+        the <literal>parents</literal> field.
+        Insert the following snippet of code immediately
+        <emphasis>before</emphasis> the <command>parents</command>
+        field declaration in the <filename>Rabbit.java</filename> file.
+        The <literal>mappedBy</literal> attribute identifies the name
+        of the owning side of the relation.
+        </para>
+              <programlisting format="linespecific">
+    @ManyToMany(mappedBy="children")
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>
+        Compile <filename>Rabbit.java</filename>.
+        </para>
+              <programlisting format="linespecific">
+javac Rabbit.java
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>
+        Enhance the <classname>Rabbit</classname> class.
+        </para>
+              <programlisting format="linespecific">
+openjpac -p persistence.xml Rabbit.java
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>
+        Refresh the object-relational mappings and database schema.
+        </para>
+              <programlisting format="linespecific">
+mappingtool -p persistence.xml Rabbit.java
+</programlisting>
+            </listitem>
+          </orderedlist>
+          <para>
+    Now that we have a Rabbit class, let's get some preliminary rabbit 
+    data into the database. 
+    </para>
+          <orderedlist>
+            <listitem>
+              <para>
+        Add a <literal>&lt;class&gt;</literal> entry for <classname>
+        Rabbit</classname> to 
+        <filename>../../META-INF/persistence.xml</filename>.
+        </para>
+              <programlisting format="linespecific">
+&lt;class&gt;tutorial.persistence.Rabbit&lt;/class&gt;
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>Create some rabbits.</para>
+              <para>
+        Run the following commands a few times to add some male
+        and female rabbits to the database:
+        </para>
+              <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance add Rabbit &lt;name&gt; false
+java tutorial.persistence.AnimalMaintenance add Rabbit &lt;name&gt; true
+</programlisting>
+              <para>
+        Now run some breeding iterations.
+        </para>
+              <programlisting format="linespecific">
+java tutorial.persistence.Rabbit breed 2
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>Look at your new rabbits.</para>
+              <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance list Rabbit
+java tutorial.persistence.AnimalMaintenance details "select r from Rabbit r where r.name = '&lt;name&gt;'"
+</programlisting>
+            </listitem>
+          </orderedlist>
+        </section>
+        <section id="jpa_tutorial_chapter5">
+          <title>Behavioral Analysis</title>
+          <para>
+    Often, pet stores sell snakes as well as rabbits and dogs.  Pet stores 
+    are primarily concerned with a snake's length; much like rabbits, pet 
+    store operators usually sell them all for a flat rate.
+    </para>
+          <para>
+    This chapter demonstrates more queries, schema manipulation, 
+    and additional relation types.
+    </para>
+          <para>
+    Provided with this tutorial is a file called <filename>Snake.java
+    </filename> which contains a sample <classname>Snake</classname> 
+    implementation. Let's get it compiled and loaded:
+    </para>
+          <orderedlist>
+            <listitem>
+              <para>
+        Examine and compile <filename>Snake.java</filename>.
+        </para>
+              <programlisting format="linespecific">
+javac Snake.java
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>Enhance the class.</para>
+              <programlisting format="linespecific">
+openjpac -p persistence.xml Snake.java
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>Refresh the mappings and database.</para>
+              <para>
+        As we have created a new persistent class, we must 
+        map it to the database and change the schema to match.  So
+        run the mapping tool:
+        </para>
+              <programlisting format="linespecific">
+mappingtool -p persistence.xml Snake.java
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>
+        Add a <literal>&lt;class&gt;</literal> entry for <classname>
+        Snake</classname> to 
+        <filename>../../META-INF/persistence.xml</filename>.
+        </para>
+              <programlisting format="linespecific">
+&lt;class&gt;tutorial.persistence.Snake&lt;/class&gt;
+</programlisting>
+            </listitem>
+          </orderedlist>
+          <para>
+    Once you have compiled everything, add a few snakes to the database 
+    using:
+    </para>
+          <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance add Snake "name" &lt;length&gt;
+</programlisting>
+          <para>
+    Where <replaceable>&lt;length&gt;</replaceable> is the length in feet 
+    for the new snake. To see the new snakes in the database, run:
+    </para>
+          <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance list Snake
+</programlisting>
+          <para>
+    Unfortunately for the massively developing rabbit population, snakes 
+    often eat rabbits. Any good inventory system should be able to capture 
+    this behavior. So, let's add some code to <filename>Snake.java
+    </filename> to support the snake's eating behavior.
+    </para>
+          <para>
+    First, let's modify <filename>Snake.java</filename> to contain a
+    list of eaten rabbits.
+    </para>
+          <orderedlist>
+            <listitem>
+              <para>
+        Add the following code snippets to
+        <filename>Snake.java</filename>.
+        </para>
+              <programlisting format="linespecific">
+    // This list will be persisted into the database as
+    // a one-to-many relation.
+    @OneToMany(mappedBy="eater")
+    private Set&lt;Rabbit&gt; giTract = new HashSet&lt;Rabbit&gt; ();
+</programlisting>
+              <para>
+        Note that we specified a <literal>mappedBy</literal>
+        attribute in this example. This is because the relation is 
+        bidirectional; that is, the rabbit has knowledge of which 
+        snake ate it. We could have left out the 
+        <literal>eater</literal> field and instead created a 
+        standard unidirectional relation.  In fact, in a bidirectional
+        many-to-one relation, the many side must always be the owner.
+        </para>
+              <para>
+        For more information on types of relations, see 
+        <xref linkend="jpa_overview_mapping_field"/> of the 
+        JPA Overview.
+        </para>
+              <para>
+          Modify the <literal>toString (boolean)</literal> method to
+        output the giTract list.
+        </para>
+              <programlisting format="linespecific">
+    public String toString (boolean detailed)
+    {
+        StringBuffer buf = new StringBuffer (1024);
+        buf.append ("Snake ").append (getName ());
+
+        if (detailed)
+        {
+            buf.append (" (").append (length).append (" feet long) sells for ");
+            buf.append (getPrice ()).append (" dollars.");
+            buf.append ("  Its gastrointestinal tract contains:\n");
+            for (Rabbit rabbit : giTract)
+                buf.append ("\t").append (rabbit).append ("\n");
+        }
+        else
+            buf.append ("; ate " + giTract.size () + " rabbits.");
+
+        return buf.toString ();
+    }
+</programlisting>
+              <para>
+        Add the following methods.
+        </para>
+              <programlisting format="linespecific">
+    /**
+     *  Kills the specified rabbit and eats it.
+     */
+    public void eat (Rabbit dinner)
+    {
+        // Consume the rabbit.
+        dinner.kill ();
+        dinner.setEater (this);
+        giTract.add (dinner);
+        System.out.println ("Snake " + getName () + " ate rabbit " 
+            + dinner.getName () + ".");
+    }
+
+
+    /**
+     *  Locates the specified snake and tells it to eat a rabbit.
+     */
+    public static void eat (EntityManager em, String filter)
+    {
+        em.getTransaction ().begin ();
+
+        // Find the desired snake(s) in the data store.
+        Query query = em.createQuery (filter);
+        List&lt;Snake&gt; results = query.getResultList ();
+        if (results.isEmpty ())
+        {
+            System.out.println ("No snakes matching '" + filter + "' found");
+            return;
+        }
+
+        Query uneatenQuery = em.createQuery
+            ("select r from Rabbit r where r.isDead = false");
+        Random random = new Random ();
+        for (Snake snake : results)
+        {
+            // Run a query for a rabbit whose 'isDead' field indicates
+            // that it is alive.
+            List&lt;Rabbit&gt; menu = uneatenQuery.getResultList ();
+            if (menu.isEmpty ())
+            {
+                System.out.println ("No live rabbits in DB.");
+                break;
+            }
+
+            // Select a random rabbit from the list.
+            Rabbit dinner = menu.get (random.nextInt (menu.size ()));
+
+            // Perform the eating.
+            System.out.println (snake + " is eating:");
+            snake.eat (dinner);
+        }
+
+        em.getTransaction ().commit ();
+    }
+
+
+    public static void main (String[] args)
+    {
+        if (args.length == 2 &amp;&amp; args[0].equals ("eat"))
+        {
+            EntityManagerFactory emf = Persistence.
+                createEntityManagerFactory (null);
+            EntityManager em = emf.createEntityManager ();
+            eat (em, args[1]);
+            em.close ();
+            emf.close ();
+            return;
+        }
+
+        // If we get here, something went wrong.
+        System.out.println ("Usage:");
+        System.out.println ("  java tutorial.persistence.Snake eat "
+            + "\"snakequery\"");
+    }
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>
+        Add an <literal>eater</literal> field to 
+        <filename>Rabbit.java</filename>, and a getter and setter.
+        </para>
+              <programlisting format="linespecific">
+    @ManyToOne @JoinColumn(name="EATER_ID")
+    private Snake eater;
+
+    ...
+
+    public Snake getEater ()
+    {
+        return eater;
+    }
+
+
+    public void setEater (Snake snake)
+    {
+        eater = snake;
+    }
+</programlisting>
+              <para>
+        The <literal>@ManyToOne</literal> annotation indicates that this
+        is the many side of the bidirectional relation.  The many side
+        must always be the owner in this type of relation.  The
+        <literal>@JoinColumn</literal> describes the foreign key
+        that joins the rabbit table to the snake table.  The rabbit
+        table has an <literal>EATER_ID</literal> column that is a
+        foreign key to the <literal>ID</literal> primary key column
+        of the snake table.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        Compile <filename>Snake.java</filename> and 
+        <filename>Rabbit.java</filename> and enhance the classes.
+        </para>
+              <programlisting format="linespecific">
+javac Snake.java Rabbit.java
+openjpac -p persistence.xml Snake.java Rabbit.java
+</programlisting>
+            </listitem>
+            <listitem>
+              <para>Refresh the mappings and database.</para>
+              <programlisting format="linespecific">
+mappingtool -p persistence.xml Snake.java Rabbit.java
+</programlisting>
+            </listitem>
+          </orderedlist>
+          <para>
+    Now, experiment with the following commands:
+    </para>
+          <programlisting format="linespecific">
+java tutorial.persistence.Snake eat "select s from Snake s where s.name = '&lt;name&gt;'"
+java tutorial.persistence.AnimalMaintenance details "select s from Snake s where s.name = '&lt;name&gt;'"
+</programlisting>
+          <section id="jpa_tutorial_chapter5_query">
+            <title>Complex Queries</title>
+            <para>
+      Imagine that one of the snakes in the database was named Killer. 
+      To find out which rabbits Killer ate, we could run either of the 
+      following two queries:
+      </para>
+            <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance details "select s from Snake s where s.name = 'Killer'"
+java tutorial.persistence.AnimalMaintenance list "select r from Rabbit r where r.eater.name = 'Killer'"
+</programlisting>
+            <para>
+      The first query is snake-centric - the query runs against the 
+      <classname>Snake</classname> class, looking for all snakes named
+      Killer and providing a detailed listing of them. The second is 
+      rabbit-centric - it examines the rabbits in the database for 
+      instances whose <literal>eater</literal> is named Killer.
+      This second query demonstrates the that simple java 'dot' syntax
+      is used when traversing an to-one field in a query.
+      </para>
+            <para>
+      It is also possible to traverse collection fields.  Imagine that 
+      there was a rabbit called Roger in the datastore and that one of 
+      the snakes ate it. In order to determine who ate Roger Rabbit, you 
+      could run a query like this:
+      </para>
+            <programlisting format="linespecific">
+java tutorial.persistence.AnimalMaintenance details "select s from Snake s inner join s.giTract r where r.name = 'Roger'"
+</programlisting>
+          </section>
+        </section>
+        <section id="jpa_tutorial-chapter6">
+          <title>Extra Features</title>
+          <para>
+    Congratulations! You are now the proud author of a pet store inventory 
+    suite. Now that you have all the major features of the pet store 
+    software implemented, it's time to add some extra features. You're on 
+    your own; think of some features that you think a pet store should have,
+    or just explore the features of JPA.
+    </para>
+          <para>
+    Here are a couple of suggestions to get you started:
+    </para>
+          <itemizedlist>
+            <listitem>
+              <para>Animal pricing.</para>
+              <para>
+        Modify <classname>Animal</classname> to contain an inventory 
+        cost and a resale price.  Calculate the real dollar amount 
+        eaten by the snakes (the sum of the inventory costs of all the 
+        consumed rabbits), and the cost assuming that all the eaten 
+        rabbits would have been sold had they been alive. Ignore the 
+        fact that the rabbits, had they lived, would have created more 
+        rabbits, and the implications of the reduced food costs due to 
+        the not-quite-as-hungry snakes and the smaller number of 
+        rabbits.
+        </para>
+            </listitem>
+            <listitem>
+              <para>Dog categorization.</para>
+              <para>
+              Modify <classname>Dog</classname> to have a
+        relation to a new class called <classname>Breed</classname>, 
+        which contains a name identifying the breed of the dog and a 
+        description of the breed. Put together an admin tool for
+              breeds and for associating dogs and breeds.
+        </para>
+            </listitem>
+          </itemizedlist>
+        </section>
+      </section>
+<!-- ### EJBDOC 
+      &ejb3-reverse-tutorial.xml;
+  -->
+      <section id="jpa_j2ee_tutorial">
+        <title>J2EE Tutorial</title>
+        <para>
+  By deploying OpenJPA into a J2EE environment, you can maintain the 
+  simplicity and performance of OpenJPA, while leveraging J2EE 
+  technologies such as container managed transactions (JTA/JTS), 
+  enterprise objects with remote invocation (EJB), and managed 
+  deployment of multi-tiered applications via an application 
+  server.  This tutorial will demonstrate how to deploy OpenJPA-based 
+  J2EE applications and showcase some basic enterprise JPA
+  design techniques. The tutorial's sample application models
+  a basic garage catalog system.  While the application is 
+  relatively trivial, the code has been constructed to illustrate 
+  simple patterns and solutions to common problems when using 
+  OpenJPA in an enterprise environment.
+  </para>
+        <section id="jpa_j2ee_tutorial_requirements">
+          <title>Prerequisites for the OpenJPA J2EE Tutorial</title>
+          <para>
+    This tutorial assumes that you have installed OpenJPA and 
+    setup your classpath according to the installation instructions 
+    appropriate for your platform.  In addition, this 
+    tutorial requires that you have installed and configured a 
+    J2EE-compliant application server, such as WebLogic or JBoss,
+    running on JDK 1.5.  If you use a different
+    application server not listed here, this tutorial may be adaptable to 
+    your application server with small changes; refer to your application
+    server's documentation for any specific classpath and deployment 
+    descriptor requirements. 
+    </para>
+          <para>
+    This tutorial assumes a reasonable level of experience with 
+    OpenJPA and JPA.  We provide a number of other 
+    tutorials for basic concepts, including enhancement, schema 
+    mapping, and configuration.  This tutorial also assumes a 
+    basic level of experience with J2EE components, including 
+    session beans, JNDI, JSP, and EAR/WAR/JAR packaging.  Sun and/or 
+    your application server company may provide tutorials to get 
+    familiar with these components.
+    </para>
+          <para>
+    In addition, this tutorial uses Ant to build the deployment 
+    archives.  While this is the preferred way of building
+    a deployment of the tutorial, one can easily build the 
+    appropriate JAR, WAR, and EAR files by hand, although that 
+    is outside the scope of this document.
+    </para>
+        </section>
+        <section id="jpa_j2ee_tutorial_installation_types">
+          <title>J2EE Installation Types</title>
+          <para>
+    Every application server has a different installation process 
+    for installing J2EE components.  OpenJPA can be installed in a 
+    number of ways, which may or may not be appropriate to your 
+    application server.  While this document focuses mainly upon 
+    using OpenJPA as a JCA resource,  there are other ways to use 
+    OpenJPA in a J2EE environment.
+    </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>JPA</literal>:  J2EE 5 allows for the
+        automatic injection of 
+        <classname>EntityManager</classname> instances
+        into the J2EE context. 
+        <!-- ### EJBDOC ###--></para>
+            </listitem>
+            <listitem>
+              <para><literal>JCA</literal>:  OpenJPA implements the 
+        JCA 1.0 spec, and the openjpa-persistence.rar file that comes in 
+        the <filename>jca/persistence</filename> directory of the 
+        distribution can be installed as any other JCA connection 
+        resource.  This is the preferred way to integrate OpenJPA into a 
+        pre-J2EE 5 environment.  It allows for simple installation 
+        (usually involving uploading or copying openjpa-persistence.rar 
+        into the application server's deployment directory), and 
+        guided configuration on many appservers<!--
+        doesn't work yet , as well as dynamic reloading 
+        for upgrading OpenJPA to a newer version-->.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        Manual Binding into JNDI: Your application may require
+        some needs in initializing OpenJPA that go beyond the 
+        JPA and JCA specifications.  In this case, you can
+        manually instantiate OpenJPA and place it into the JNDI tree.
+        This process, however, is not seamless and can require a 
+        fair bit of custom application server code to bind an 
+        instance of 
+        <classname>org.apache.openjpa.persistence.EntityManagerFactoryImpl</classname>
+        into JNDI. 
+        </para>
+            </listitem>
+          </itemizedlist>
+        </section>
+        <section id="jpa_j2ee_tutorial_installing_sample">
+          <title>Installing the J2EE Sample Application</title>
+          <para>
+    Installing the sample application involves first compiling
+    and building a deployment archive (.ear) file.  This file
+    then needs to be deployed into your application server.
+    </para>
+          <section id="jpa_j2ee_tutorial_building_sample">
+            <title>Compiling and Building The Sample Application</title>
+            <para>
+      Navigate to the <filename>samples/persistence/j2ee</filename> 
+      directory of your OpenJPA installation.
+      </para>
+            <para>
+      Ensure that the JNDI name in the setSessionContext() method in
+      ejb/CarBean.java matches your JCA installation. This defaults to
+      <literal>java:/openjpa-ejb</literal>, but the actual value will depend
+      on the configuration of your JCA deploy and your application 
+      server's JNDI context.  E.g. the default name for a WebLogic 9 
+      install would be simply <literal>openjpa-ejb</literal>.
+      </para>
+            <para>
+      Compile the source files in place both in this base directory 
+      as well as the nested <filename>ejb</filename> and 
+      <filename>jsp</filename> directories:
+      </para>
+            <programlisting format="linespecific">
+javac *.java  ejb/*.java jsp/*.java
+</programlisting>
+            <para>
+      Enhance the Car class. 
+      </para>
+            <programlisting format="linespecific">
+openjpac -p persistence.xml Car.java
+</programlisting>
+            <para>
+      Run the mapping tool; make sure that your <filename>
+      META-INF/persistence.xml</filename> file includes the same 
+      connection information (e.g. Driver, URL, etc.) as your 
+      JCA installation.  You should update your JCA configuration
+      to include <classname>samples.persistence.j2ee.Car</classname>
+      in the <link linkend="openjpa.MetaDataFactory">MetaDataFactory</link> 
+      property:
+      </para>
+            <programlisting format="linespecific">
+&lt;config-property name="MetaDataFactory"&gt;Types=samples.persistence.j2ee.Car&lt;/config-property/&gt;
+</programlisting>
+            <programlisting format="linespecific">
+mappingtool -p persistence.xml Car.java
+</programlisting>
+            <para>
+      Build an J2EE application archive by running Ant against the 
+      <filename>build.xml</filename>.  This will create 
+      <filename>openjpa-persistence-j2ee-sample.ear</filename>.  This ear 
+      can now be deployed to your appserver.  Be sure to add the class
+      <classname>samples.j2ee.Car</classname> to the
+      <literal>openjpa.PersistentClasses</literal> OpenJPA configuration
+      property.  This will automatically register the Entity.
+      </para>
+            <programlisting format="linespecific">
+ant -f build.xml
+</programlisting>
+          </section>
+          <section id="jpa_j2ee_tutorial_sample_jboss">
+            <title>Deploying Sample To JBoss</title>
+            <para>
+      Place the ear file in the <filename>deploy</filename> 
+      directory of your JBoss installation.  You can use the 
+      above hints to view the JNDI tree to see if 
+      <classname>samples.j2ee.ejb.CarHome</classname> was 
+      deployed to JNDI.
+      </para>
+          </section>
+          <section id="jpa_j2ee_tutorial_sample_weblogic">
+            <title>Deploying Sample To WebLogic 9</title>
+            <para>
+      Place the ear file in the <filename>autodeploy</filename>
+      directory of your WebLogic domain.  Production mode (see your 
+      startWebLogic.sh/cmd file) should be set to false to enable 
+      auto-deployment.  If the application was installed correctly, 
+      you should see <computeroutput>openjpa-persistence-j2ee-sample
+      </computeroutput> listed in the Deployments section of the admin 
+      console.  In addition you should find <literal>CarHome</literal> 
+      listed in the JNDI tree under 
+      <computeroutput>AdminServer-&gt;samples-&gt;j2ee-&gt;ejb
+      </computeroutput>.  Ensure that you have added the class
+      <classname>samples.j2ee.Car</classname> to the
+      <literal>openjpa.PersistentClasses</literal> OpenJPA configuration
+      property in the <literal>META-INF/ra.xml</literal> file.
+      </para>
+          </section>
+<!-- TODO 
+    <section id="jpa_j2ee_tutorial_sample_weblogic8">
+      <title>Deploying Sample To WebLogic 8.1</title>
+      <para>
+      Create a new directory named <filename>
+      openjpa-persistence-j2ee-sample.ear</filename>
+      in the <filename>applications</filename> directory of
+      your WebLogic domain.  Extract the EAR file (without copying
+      the EAR file) to this new directory:
+      </para>
+<programlisting>
+applications> mkdir openjpa-persistence-j2ee-sample.ear
+applications> cd openjpa-persistence-j2ee-sample.ear
+openjpa-persistence-j2ee-sample.ear> jar -xvf /path/to/openjpa-persistence-j2ee-sample.ear
+</programlisting>
+      <para>
+      Deploy the application by using the admin console
+      (Deployments -&gt; Applications -&gt; Deploy a new Application.
+      Select <literal>openjpa-persistence-j2ee-sample.ear</literal> and 
+      deploy to the proper server targets.  If you have installed the
+      application correctly, you should find CarHome
+      listed in the JNDI tree under
+      <computeroutput>myserver-&gt;samples-&gt;j2ee-&gt;ejb
+      </computeroutput>.
+      </para>
+    </section>
+    <section id="jpa_j2ee_tutorial_sample_sunone">
+      <title>Deploying Sample To SunONE / Sun JES</title>
+      <para>
+      Browse to the admin console in your web browser. Select 
+      <computeroutput>Applications/ Enterprise Applications
+      </computeroutput> from the left navigation panel.  Select 
+      <computeroutput>Deploy... </computeroutput> and in the 
+      following screen upload the <filename>
+      openjpa-persistence-j2ee-sample.ear</filename> 
+      file to the server.  Apply your changes by selecting the 
+      link in the upper right portion of the page.  You should 
+      now see <computeroutput>openjpa-persistence-j2ee-sample
+      </computeroutput> listed 
+      in the Enterprise Applications folder of the navigation panel.
+      </para>
+    </section>
+    <section id="jpa_j2ee_tutorial_sample_jrun">
+      <title>Deploying Sample To JRun</title>
+      <para>
+      Browse to the admin console in your web browser. Select 
+      <computeroutput>J2EE Components
+      </computeroutput> from the left navigation panel.  Select 
+      <computeroutput>Add</computeroutput> under the
+      <computeroutput>Enterprise Applications</computeroutput>
+      heading. Select the <filename>openjpa-persistence-j2ee-sample.ear
+      </filename> file and hit <computeroutput>Deploy</computeroutput>.
+      You should now see <computeroutput>Sample-OpenJPAJ2EE</computeroutput>
+      listed in the top-level folder of the navigation panel.
+      Select it, and then select the
+      <computeroutput>sample-ejb.jar#CarEJB</computeroutput>
+      component under
+      <computeroutput>Enterprise JavaBeans</computeroutput>
+      section, then change the <computeroutput>JNDI Name</computeroutput>
+      for the bean from the default value to
+      <computeroutput>samples.j2ee.ejb.CarHome</computeroutput> and hit
+      <computeroutput>Apply</computeroutput>.
+      </para>
+      <para>
+      If the OpenJPA resource adapter and the sample EAR are both
+      configured correctly, you should now be able to access
+      your sample application at JRun's deploy URL (e.g.,
+      <literal>http://localhost:8100/sample/</literal>).
+      </para>
+    </section>
+    <section id="jpa_j2ee_tutorial_sample_websphere">
+      <title>Deploying Sample To WebSphere</title>
+      <para>
+      Browse to the admin console in your web browser.  Select 
+      <computeroutput>Applications / Install New Application
+      </computeroutput> from the left navigation panel.  Select 
+      the path to your <filename>openjpa-persistence-j2ee-sample.ear
+      </filename> file and press <computeroutput>Next</computeroutput>.
+      </para>
+      <para>
+      On the following screen, leave the options at the default 
+      and select <computeroutput>Next</computeroutput>.  On the following
+      screen (<computeroutput>Install New Application->Step 1
+      </computeroutput>), ensure that the <computeroutput>Deploy EJBs
+      </computeroutput> option is checked.  Leave other options at their 
+      defaults.
+      </para>
+      <para>
+      Move on to Step 2.  On this screen enter <literal>
+      samples.j2ee.ejb.CarHome</literal> as the JNDI name for the 
+      <classname>Car</classname> EJB.  Continue through the 
+      remaining steps leaving options at the defaults.  Select 
+      <computeroutput>Finish</computeroutput> and ensure that 
+      the application is deployed correctly.
+      </para>
+      <para>
+      Save the changes to the domain configuration by either 
+      selecting the <computeroutput>Save</computeroutput> link 
+      that appears after the installation is complete or by 
+      selecting <computeroutput>Save</computeroutput> from the top menu.
+      </para>
+      <para>
+      To verify your installation, select <computeroutput>Applications 
+      / Enterprise Applications</computeroutput> from the left 
+      navigation panel.  <computeroutput>Sample-OpenJPAJ2EE</computeroutput> 
+      should be listed in the list.  If the application has not 
+      started already, select the checkbox next to <computeroutput>
+      Sample-OpenJPAJ2EE</computeroutput>
+      and select <computeroutput>Start</computeroutput>.  
+      </para>
+    </section>
+    <section id="jpa_j2ee_tutorial_sample_borland">
+      <title>Deploying Sample To Borland Enterprise Server 5.2</title>
+      <para>
+      Deploy the EAR file using iastool or the console.  Note
+      that you may have to include the JDO library in your
+      stub generation process.  Also be sure that you have 
+      followed the JCA instructions for
+      BES as well as editing the ejb/CarBean.java file to
+      point to <literal>serial://openjpa-ejb</literal> JNDI location.
+      You should be able to see the CarEJB located in JNDI
+      located at the home classname.
+      </para>
+    </section>
+    -->
+        </section>
+        <section id="jpa_j2ee_tutorial_using">
+          <title>Using The Sample Application</title>
+          <para>
+    The sample application installs itself into the web layer at the 
+    context root of sample.  By browsing to 
+    <computeroutput>http://yourserver:yourport/openjpa-persistence-j2ee-sample
+    </computeroutput>, you should be presented with a simple 
+    list page with no cars.  You can edit, add, delete car instances.
+    In addition, you can query on the underlying <classname>Car</classname>
+    instances by passing in an JPQL query into the marked form (such as
+    <computeroutput>select car from Car car where car.model="Some Model"</computeroutput>).
+    </para>
+        </section>
+        <section id="jpa_j2ee_tutorial_architecture">
+          <title>Sample Architecture</title>
+          <para>
+    The garage application is a simple enterprise application that 
+    demonstrates some of the basic concepts necessary when 
+    using OpenJPA in the enterprise layer.
+    </para>
+          <para>
+    The core model wraps a stateless session bean facade around 
+    an entity.  Using a session bean provides both a remote interface 
+    for various clients as well as providing a transactional context in 
+    which to work (and thus avoiding any explicit transactional code).  
+    </para>
+          <para>
+    This session bean uses the JPA's detachment 
+    capabilities to provide an automatic Data Transfer Object mechanism
+    for the primary communication between the
+    application server and the (possibly remote) client. The <classname>Car
+    </classname> instance will be used as the primary object upon
+    which the client will work.
+    </para>
+          <itemizedlist>
+            <listitem>
+              <para><literal>samples/persistence/j2ee/Car.java</literal>:
+        The core of the sample application.  This is the 
+        entity class that OpenJPA will use to persist the 
+        application data.  
+        Instances of this class will also fill the role of 
+        data transfer object (DTO) for EJB clients.  
+        To accomplish this, <classname>Car</classname> implements 
+        <classname>java.io.Serializable</classname> 
+        so that remote clients can access cars as parameters
+        and return values from the EJB.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>
+        samples/persistence/j2ee/jsp/SampleUtilities.java</literal>:
+        This is a simple facade to aggregate some common J2EE 
+        behavior into some static methods.  
+        By placing all of the functionality into a single 
+        facade class, we can reduce code maintenance of our JSPs.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>samples/persistence/j2ee/ejb/Car*.java</literal>:
+        The source for the <classname>CarEJB</classname> session bean.  
+        Clients can use the <classname>CarHome</classname> 
+        and <classname>CarRemote</classname> interfaces to 
+        find, manipulate, and persist changes to 
+        <classname>Car</classname> transfer object 
+        instances.  By using J2EE transactional features,
+        the implementation code in <filename>CarBean.java</filename> 
+        can be focused almost entirely upon business and 
+        persistence logic without worrying about transactions. 
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>samples/persistence/j2ee/jsp/*.jsp</literal>:
+        The web presentation client.  These JSPs are not aware of the
+        JPA; they simply use the <classname>CarEJB</classname> session 
+        bean and the <classname>Car</classname> transfer object to do 
+        all the work.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>samples/persistence/j2ee/resources/*</literal>:
+        Files required to deploy to the various appservers, 
+        including J2EE deployment descriptors, WAR/ EJB/ EAR 
+        descriptors, as well as appserver specific files.
+        </para>
+            </listitem>
+            <listitem>
+              <para><literal>samples/persistence/j2ee/build.xml</literal>:
+        A simple Ant build file to help in creating a J2EE EAR file.
+        </para>
+            </listitem>
+          </itemizedlist>
+        </section>
+        <section id="jpa_j2ee_tutorial_notes">
+          <title>Code Notes and J2EE Tips</title>
+          <orderedlist>
+            <listitem>
+              <para>
+        Entity classes are excellent 
+        candidates for the Data Transfer Object Pattern.   
+        This pattern attempts to reduce network load, as well 
+        as group business logic into concise units.  
+        For example, <methodname>CarBean.edit</methodname> allows you 
+        to ensure that all values are correct before committing a 
+        transaction, instead of sequentially calling getters and 
+        setters on the session facade.  This is especially true when 
+        using RMI such as from a Swing based application 
+        connecting to an application server.
+        </para>
+              <para><classname>CarEJB</classname> works as a session bean facade 
+        to demarcate transactions, provide finder methods, and 
+        encapsulate complex business logic at the server level.
+        </para>
+            </listitem>
+            <listitem>
+              <para><methodname>EntityManager.close()</methodname> 
+        should be called at the end of every EJB method.  
+        In addition to ensuring that your code will not attempt to 
+        access a closed <classname>EntityManager</classname>, it 
+        allows OpenJPA to free up unused resources.
+        Since an <classname>EntityManager</classname> is created 
+        for every transaction, this can increase the scalability
+        of your application.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        You should not use <methodname>
+        EntityManager.getTransaction()</methodname> when using JTA
+        to manage your transactions. Instead, OpenJPA will integrate with
+        JTA to automatically govern transactions based on your EJB
+        transaction configuration.
+        </para>
+            </listitem>
+            <listitem>
+              <para>
+        While serialization of entity instances is relatively 
+        straightforward, there are several things to keep in mind:
+        </para>
+              <itemizedlist>
+                <listitem>
+                  <para>
+            While "default fetch group" values will always be 
+            returned to the client upon serialization, lazily 
+            loaded fields will not as the 
+            <classname>EntityManager</classname> will 
+            have been closed before those fields attempt to 
+            serialize.  You can either access those fields 
+            before serialization, configure the fetch type of the
+            relationships, or configure your JPQL queries to 
+            eagerly fetch data.
+            </para>
+                </listitem>
+              </itemizedlist>
+            </listitem>
+            <listitem>
+              <para>
+        It is not necessarily required that you use EJBs and 
+        container-managed transactions to demarcate transactions, 
+        although that is probably the most common method.  
+        In EJBs using bean managed transactions, you can control
+        transactions through the
+        <classname>javax.transaction.UserTransaction</classname> interface.
+        Furthermore, outside of session beans you can control the 
+        JPA layer's transaction via the 
+        <classname>javax.persistence.EntityTransaction</classname> 
+        interface.
+        </para>
+            </listitem>
+            <listitem>
+              <para><classname>EntityManager</classname>s are allocated on a 
+        per-Transaction basis. 
+        Calling <methodname>getEntityManager</methodname> from 
+        the same <classname>EntityManagerFactory</classname> 
+        within the same EJB method call will always return the same
+        entity manager, although the user-visible object may be 
+        proxied, so might not compare equal using the 
+        <literal>==</literal> operator.  
+        </para>
+            </listitem>
+          </orderedlist>
+        </section>
+      </section>
+    </chapter>



Mime
View raw message