You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by mp...@apache.org on 2006/07/26 06:24:30 UTC
svn commit: r425608 [2/3] - in /incubator/openjpa/trunk: ./ openjpa-jdbc-5/
openjpa-jdbc/ openjpa-kernel-5/ openjpa-kernel/ openjpa-lib/
openjpa-persistence-jdbc/ openjpa-persistence/ openjpa-project/
openjpa-project/src/ openjpa-project/src/doc/ openj...
Added: incubator/openjpa/trunk/openjpa-project/src/doc/manual/manual.xml
URL: http://svn.apache.org/viewvc/incubator/openjpa/trunk/openjpa-project/src/doc/manual/manual.xml?rev=425608&view=auto
==============================================================================
--- incubator/openjpa/trunk/openjpa-project/src/doc/manual/manual.xml (added)
+++ incubator/openjpa/trunk/openjpa-project/src/doc/manual/manual.xml Tue Jul 25 21:24:28 2006
@@ -0,0 +1,33806 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [ <!ENTITY openjpa-version "VERSION"> ]>
+<book id="manual">
+ <bookinfo>
+ <title>OpenJPA Developers Guide</title>
+ </bookinfo>
+ <part id="introduction">
+ <title>Introduction</title>
+ <chapter id="openjpa_intro">
+ <title>OpenJPA <phrase>JPA</phrase></title>
+ <indexterm zone="openjpa_intro">
+ <primary>OpenJPA <phrase>JPA</phrase></primary>
+ </indexterm>
+ <para>
+ OpenJPA <phrase>JPA</phrase> is Apache's implementation of Sun's
+ <phrase>
+ Java Persistence API (JPA) specification</phrase>
+
+
+ for the transparent persistence of Java objects.
+ This document provides an overview of
+ <phrase>the JPA standard</phrase>
+
+
+ and technical details on the use of OpenJPA <phrase>JPA</phrase>.
+ </para>
+ <para>
+ To quickly get started with JPA, you may want to begin at
+ <xref linkend="jpa_tutorial"/>.
+ If you would prefer to start with an introduction to the concepts of JPA,
+ begin with <xref linkend="jpa_overview_intro"/>.
+ </para>
+ <section id="openjpa_intro_about">
+ <title>About This Document</title>
+ <para>
+ This document is intended for OpenJPA users. It is divided into several
+ parts:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <link linkend="jpa_overview_intro">JPA Overview</link>
+ describes the fundamentals of JPA.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In the <link linkend="tutorials">OpenJPA <phrase>JPA</phrase>
+ Tutorials</link> you will develop simple persistent applications
+ using OpenJPA. Through the tutorials' hands-on approach, you
+ will become comfortable with the core tools and development
+ processes under OpenJPA <phrase>JPA</phrase>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <link linkend="ref_guide_intro">OpenJPA <phrase>JPA</phrase>
+ Reference Guide</link> contains detailed documentation on all
+ aspects of OpenJPA <phrase>JPA</phrase>. Browse through this guide to
+ familiarize yourself with the many advanced features and
+ customization opportunities OpenJPA provides. Later, you can use
+ the guide when you need details on a specific aspect of OpenJPA
+ <phrase>JPA</phrase>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </chapter>
+ </part>
+ <part id="jpa_overview">
+ <title>Java Persistence API</title>
+ <chapter id="jpa_overview_intro">
+ <title>Introduction</title>
+ <para><indexterm><primary>EJB3 Persistence</primary><see>EJB</see></indexterm><indexterm><primary>EJB</primary></indexterm>
+ Enterprise Java Beans 3.0 Persistence (EJB persistence) is a specification
+ from Sun Microsystems for the persistence of Java objects to any relational
+ datastore. EJB persistence requires J2SE 1.5 (also referred to as "Java 5")
+ or higher, as it makes heavy use of new Java language features such as
+ annotations and generics. This document provides an overview of EJB
+ persistence. Unless otherwise noted, the information presented
+ applies to all EJB persistence implementations.
+ </para>
+ <note>
+ <para>
+ This document describes the Public Draft of the EJB 3.0
+ persistence specification.
+ </para>
+ <para>
+ For coverage of OpenJPA's many extensions to the EJB persistence
+ specification, see the <link linkend="ref_guide_intro">Reference
+ Guide</link>.
+ </para>
+ </note>
+ <section id="jpa_overview_intro_audience">
+ <title>Intended Audience</title>
+ <para>
+ This document is intended for developers who want to learn about
+ EJB persistence in order to use it in their applications.
+ It assumes that you have a strong knowledge of object-oriented concepts
+ and Java, including Java 5 annotations and generics. It also assumes
+ some experience with relational databases and the
+ Structured Query Language (SQL).
+ </para>
+ </section>
+ <section id="jpa_overview_intro_transpers">
+ <title>Lightweight Persistence</title>
+ <indexterm zone="jpa_overview_intro_transpers">
+ <primary>lightweight persistence</primary>
+ </indexterm>
+ <para><indexterm><primary>persistent data</primary></indexterm><emphasis>Persistent data</emphasis> is information that can
+ outlive the program that creates it. The majority of complex
+ programs use persistent data: GUI applications need to store user
+ preferences across program invocations, web applications track
+ user movements and orders over long periods of time, etc.
+ </para>
+ <para><emphasis>Lightweight persistence</emphasis> is the storage and
+ retrieval of persistent data with little or no work from you, the
+ developer. For example, Java serialization<indexterm><primary>serialization</primary></indexterm> is a form of
+ lightweight persistence because it can be used to persist Java
+ objects directly to a file with very little effort. Serialization's
+ capabilities as a lightweight persistence mechanism pale in
+ comparison to those provided by EJB, however. The next
+ chapter compares EJB to serialization and other available
+ persistence mechanisms.
+ </para>
+ </section>
+ </chapter>
+ <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>
+ <chapter id="jpa_overview_arch">
+ <title>EJB Persistence Architecture</title>
+ <indexterm zone="jpa_overview_arch">
+ <primary>EJB</primary>
+ <secondary>architecture</secondary>
+ </indexterm>
+ <para>
+ The diagram below illustrates the relationships between the primary
+ components of the EJB architecture.
+ </para>
+ <mediaobject>
+ <imageobject>
+<!-- PNG image data 400 x 256 (see README) -->
+ <imagedata fileref="img/ejb3-arch.png" width="267px"/>
+ </imageobject>
+ <textobject>
+ <phrase>EJB architecture</phrase>
+ </textobject>
+ </mediaobject>
+ <note>
+ <para>
+ A number of the depicted interfaces are only required outside of
+ an EJB3-compliant application server. In an application server,
+ <classname>EntityManager</classname> instances are typically injected,
+ rendering the <classname>EntityManagerFactory</classname> unnecessary.
+ Also, transactions within an application server
+ are handled using standard application server transaction controls.
+ Thus, the <classname>EntityTransaction</classname> also goes unused.
+ </para>
+ </note>
+ <itemizedlist>
+ <listitem>
+ <para><indexterm><primary>Persistence</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_persistence"><classname>Persistence</classname></link></emphasis>:
+ The <classname>javax.persistence.Persistence</classname> class
+ contains static helper methods to obtain
+ <classname>EntityManagerFactory</classname> instances in a
+ vendor-neutral fashion.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>EntityManagerFactory</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_emfactory"><classname>EntityManagerFactory</classname></link></emphasis>: The <classname>javax.persistence.EntityManagerFactory
+ </classname> class is a factory for <classname>
+ EntityManager</classname>s.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>EntityManager</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_em"><classname>EntityManager</classname></link></emphasis>:
+ The <classname>javax.persistence.EntityManager</classname> is the
+ primary EJB persistence interface used by applications.
+ Each <classname>EntityManager</classname> manages a set of
+ persistent objects, and has APIs to insert new objects and delete
+ existing ones. When used outside the container, there is a
+ one-to-one relationship between an
+ <classname>EntityManager</classname> and an <classname>
+ EntityTransaction</classname>. <classname>
+ EntityManager</classname>s also act as factories for
+ <classname>Query</classname> instances.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>entity</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_pc"><classname>Entity</classname></link></emphasis>:
+ Entites are persistent objects that represent datastore records.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>EntityTransaction</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_trans"><classname>EntityTransaction</classname></link></emphasis>:
+ Each <classname>EntityManager</classname> has a one-to-one
+ relation with a single
+ <classname>javax.persistence.EntityTransaction</classname>.
+ <classname>EntityTransaction</classname>s allow operations on
+ persistent data to be grouped into units of work that either
+ completely succeed or completely fail, leaving the datastore
+ in its original state. These all-or-nothing operations are
+ important for maintaining data integrity.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>Query</primary></indexterm><indexterm><primary>EJB3 Persistence Query Language</primary><see>JPQL</see></indexterm><indexterm><primary>JPQL</primary></indexterm><indexterm><primary>EJB</primary><secondary>query language</secondary><see>JPQL</see></indexterm><indexterm><primary>Structured Query Language</primary><see>SQL</see></indexterm><indexterm><primary>SQL</primary></indexterm><emphasis role="bold"><link linkend="jpa_overview_query"><classname>Query</classname></link></emphasis>: The
+ <classname>javax.persistence.Query</classname> interface is
+ implemented by each EJB vendor to find persistent objects
+ that meet certain criteria. EJB standardizes support
+ for queries using both the EJB Query Language (JPQL) and
+ the Structured Query Language (SQL). You obtain
+ <classname>Query</classname> instances from an
+ <classname>EntityManager</classname>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The example below illustrates how the EJB interfaces interact to
+ execute an JPQL query and update persistent objects. The example
+ assumes execution outside a container.
+ </para>
+ <example id="jpa_overview_arch_interact_outside">
+ <title>Interaction of Interfaces Outside Container</title>
+ <programlisting format="linespecific">
+// get an EntityManagerFactory using the Persistence class; typically
+// the factory is cached for easy repeated use
+EntityManagerFactory factory = Persistence.createEntityManagerFactory (null);
+
+// get an EntityManager from the factory
+EntityManager em = factory.createEntityManager (PersistenceContextType.EXTENDED);
+
+// updates take place within transactions
+EntityTransaction tx = em.getTransaction ();
+tx.begin ();
+
+// query for all employees who work in our research division
+// and put in over 40 hours a week average
+Query query = em.createQuery ("select e from Employee e where "
+ + "e.division.name = 'Research' AND e.avgHours > 40");
+List results = query.getResultList ();
+
+// give all those hard-working employees a raise
+for (Object res : results)
+{
+ Employee emp = (Employee) res;
+ emp.setSalary (emp.getSalary () * 1.1);
+}
+
+// commit the updates and free resources
+tx.commit ();
+em.close ();
+factory.close ();
+</programlisting>
+ </example>
+ <para>
+ Within a container, the <classname>EntityManager</classname> will be
+ injected and transactional handled declaratively. Thus, the in-container
+ version of the example consists entirely of business logic:
+ </para>
+ <example id="jpa_overview_arch_interact_inside">
+ <title>Interaction of Interfaces Inside Container</title>
+ <programlisting format="linespecific">
+// query for all employees who work in our research division
+// and put in over 40 hours a week average - note that the EntityManager em
+// is injected using a @Resource annotation
+Query query = em.createQuery ("select e from Employee e where "
+ + "e.division.name = 'Research' and e.avgHours > 40");
+List results = query.getResultList ();
+
+// give all those hard-working employees a raise
+for (Object res : results)
+{
+ emp = (Employee) res;
+ emp.setSalary (emp.getSalary () * 1.1);
+}
+</programlisting>
+ </example>
+ <para>
+ The remainder of this document explores the EJB interfaces in
+ detail. We present them in roughly the order that you will use them as you
+ develop your application.
+ </para>
+ <section id="jpa_overview_arch_exceptions">
+ <title>EJB Exceptions</title>
+ <indexterm zone="jpa_overview_arch_exceptions">
+ <primary>EJB</primary>
+ <secondary>exceptions</secondary>
+ <seealso>exceptions</seealso>
+ </indexterm>
+ <indexterm>
+ <primary>exceptions</primary>
+ <secondary>EJB</secondary>
+ </indexterm>
+ <mediaobject>
+ <imageobject>
+<!-- PNG image data, 427 x 355 (see README) -->
+ <imagedata fileref="img/ejb3-exceptions.png" width="285px"/>
+ </imageobject>
+ <textobject>
+ <phrase>EJB persistence exception architecture</phrase>
+ </textobject>
+ </mediaobject>
+ <para>
+ The diagram above depicts the EJB persistence exception architecture.
+ All exceptions are unchecked. EJB persistence uses
+ standard exceptions where appropriate, most notably <classname>
+ IllegalArgumentException</classname>s and <classname>
+ IllegalStateException</classname>s. The specification also provides
+ a few EJB-specific exceptions in the <literal>javax.persistence
+ </literal> package. These exceptions should be self-explanatory. See
+ the <ulink url="http://java.sun.com/javaee/5/docs/api">Javadoc</ulink> for
+ additional details on EJB exceptions.
+ </para>
+ <note>
+ <para>
+ All exceptions thrown by OpenJPA implement
+ <ulink url="../apidocs/org/apache/openjpa/util/ExceptionInfo.html"><classname>
+ org.apache.openjpa.util.ExceptionInfo</classname></ulink> to provide you with
+ additional error information.
+ </para>
+ </note>
+ </section>
+ </chapter>
+<!-- author: Abe White -->
+ <chapter id="jpa_overview_pc">
+ <title>Entity</title>
+ <indexterm zone="jpa_overview_pc">
+ <primary>persistent classes</primary>
+ </indexterm>
+ <indexterm zone="jpa_overview_pc">
+ <primary>Entity</primary>
+ <seealso>persistent classes</seealso>
+ </indexterm>
+ <indexterm>
+ <primary>class</primary>
+ <secondary>persistent</secondary>
+ <see>persistent classes</see>
+ </indexterm>
+ <indexterm>
+ <primary>persistence capable</primary>
+ <see>Entity</see>
+ </indexterm>
+ <para>
+ JPA recognizes two types of persistent classes: <emphasis>
+ entity</emphasis> classes and <emphasis>embeddable</emphasis> classes.
+ Each persistent instance of an entity class - each
+ <emphasis>entity</emphasis> - represents a unique datastore
+ record. You can use the <classname>EntityManager</classname> to find an
+ entity by its persistent identity (covered later in this chapter), or use
+ a <classname>Query</classname> to find entities matching certain criteria.
+ </para>
+ <para>
+ An instance of an embeddable class, on the other hand, is only stored
+ as part of a separate entity. Embeddable instances have no
+ persistent identity, and are never returned directly from the
+ <classname>EntityManager</classname> or from a <classname>Query</classname>.
+ </para>
+ <para>
+ Despite these differences, there are few differences between entity classes
+ and embeddable classes. In fact, writing either type
+ of persistent class is little different than writing any other
+ class. There are no special parent classes to extend from, field types to
+ use, or methods to write. This is one important way in which JPA makes
+ persistence transparent to you, the developer.
+ </para>
+ <note>
+ <para>
+ JPA supports both fields and JavaBean properties
+ as persistent state. For simplicity, however, we will
+ refer to all persistent state as persistent fields, unless we
+ want to note a unique aspect of persistent properties.
+ </para>
+ </note>
+ <example id="jpa_overview_pc_pcclass">
+ <title>Persistent Class</title>
+ <programlisting format="linespecific">
+package org.mag;
+
+/**
+ * Example persistent class. Notice that it looks exactly like any other
+ * class. JPA makes writing persistent classes completely transparent.
+ */
+public class Magazine
+{
+ private String isbn;
+ private String title;
+ private Set articles = new HashSet ();
+ private Article coverArticle;
+ private int copiesSold;
+ private double price;
+ private Company publisher;
+ private int version;
+
+ protected Magazine ()
+ {
+ }
+
+ public Magazine (String title, String isbn)
+ {
+ this.title = title;
+ this.isbn = isbn;
+ }
+
+ public void publish (Company publisher, double price)
+ {
+ this.publisher = publisher;
+ publisher.addMagazine (this);
+ this.price = price;
+ }
+
+ public void sell ()
+ {
+ copiesSold++;
+ publisher.addRevenue (price);
+ }
+
+ public void addArticle (Article article)
+ {
+ articles.add (article);
+ }
+
+ // rest of methods omitted
+}
+</programlisting>
+ </example>
+ <section id="jpa_overview_pc_restrict">
+ <title>Restrictions on Persistent Classes</title>
+ <indexterm zone="jpa_overview_pc_restrict">
+ <primary>persistent classes</primary>
+ <secondary>restrictions on</secondary>
+ </indexterm>
+ <para>
+ There are very few restrictions placed on persistent classes.
+ Still, it never hurts to familiarize yourself with exactly what
+ JPA does and does not support.
+ </para>
+ <section id="jpa_overview_pc_no_arg">
+ <title>Default or No-Arg Constructor</title>
+ <indexterm zone="jpa_overview_pc_no_arg">
+ <primary>persistent classes</primary>
+ <secondary>no-arg constructor requirement</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>constructor</primary>
+ <secondary>no-arg constructor requirement</secondary>
+ </indexterm>
+ <para>
+ The JPA specification requires that all persistent
+ classes have a no-arg constructor. This constructor
+ may be public or protected. Because the compiler automatically
+ creates a default no-arg constructor when no other constructor
+ is defined, only classes that define constructors must also
+ include a no-arg constructor.
+ </para>
+ <note>
+ <para>
+ OpenJPA's <emphasis>enhancer</emphasis> will automatically add a
+ protected no-arg constructor to your class when required.
+ Therefore, this restriction does not apply when using
+ OpenJPA. See <xref linkend="ref_guide_pc_enhance"/>
+ of the Reference Guide for details.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_pc_final">
+ <title>Final</title>
+ <para>
+ Entity classes may not be final. No method of an entity class can
+ be final.
+ </para>
+ <note>
+ <para>
+ OpenJPA supports final classes and final methods.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_pc_id">
+ <title>Identity Fields</title>
+ <indexterm zone="jpa_overview_pc_id">
+ <primary>identity fields</primary>
+ <seealso>persistent fields</seealso>
+ </indexterm>
+ <indexterm zone="jpa_overview_pc_id">
+ <primary>persistent classes</primary>
+ <secondary>JPA id requirement</secondary>
+ </indexterm>
+ <para>
+ All entity classes must declare one or more fields which together
+ form the persistent identity of an instance. These are called
+ <emphasis>identity</emphasis> or <emphasis>primary key</emphasis>
+ fields. In our <classname>Magazine</classname> class,
+ <literal>isbn</literal> and
+ <literal>title</literal> are identity fields, because no two
+ magazine records in the datastore can have the same
+ <literal>isbn</literal> and <literal>title</literal> values.
+ <xref linkend="jpa_overview_meta_id"/> will show you how to denote
+ your identity fields in JPA metadata.
+ <xref linkend="jpa_overview_pc_identity"/> below examines
+ persistent identity.
+ </para>
+ <note>
+ <para>
+ OpenJPA fully supports identity fields, but does not require them.
+ See <xref linkend="ref_guide_pc_oid"/> of the Reference
+ Guide for details.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_pc_version">
+ <title>Version Field</title>
+ <indexterm zone="jpa_overview_pc_version">
+ <primary>version fields</primary>
+ <seealso>persistent fields</seealso>
+ </indexterm>
+ <indexterm zone="jpa_overview_pc_version">
+ <primary>persistent classes</primary>
+ <secondary>JPA version requirement</secondary>
+ </indexterm>
+ <para>
+ The <literal>version</literal> field in our <classname>Magazine
+ </classname> class may seem out of place.
+ JPA uses a version field in your entity to detect
+ concurrent modifications to the same datastore record. When the
+ JPA runtime detects an attempt to concurrently modify
+ the same record, it throws an exception to the transaction
+ attempting to commit last. This prevents overwriting the previous
+ commit with stale data.
+ </para>
+ <para>
+ The version field is not required, but without one concurrent
+ threads or processes might succeed in making conflicting changes
+ to the same record at the same time. This is unacceptable to most
+ applications. <xref linkend="jpa_overview_meta_version"/>
+ shows you how to designate a version field in JPA metadata.
+ </para>
+ <para>
+ The version field must be an integral type (<classname>
+ int</classname>, <classname>Long</classname>, etc) or a
+ <classname>java.sql.Timestamp</classname>. You should consider
+ version fields immutable. Changing the field value has undefined
+ results.
+ </para>
+ <note>
+ <para>
+ OpenJPA fully supports version fields, but does not require them
+ for concurrency detection. OpenJPA can maintain
+ surrogate version values or use state comparisons to detect
+ concurrent modifications. See
+ <xref linkend="ref_guide_mapping_ejb"/> in the Reference Guide.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_pc_restrict_inheritance">
+ <title>Inheritance</title>
+ <indexterm zone="jpa_overview_pc_restrict_inheritance">
+ <primary>persistent classes</primary>
+ <secondary>inheritance of</secondary>
+ <seealso>inheritance</seealso>
+ </indexterm>
+ <indexterm>
+ <primary>inheritance</primary>
+ <secondary>of persistent classes</secondary>
+ </indexterm>
+ <para>
+ JPA fully supports inheritance in persistent classes.
+ It allows persistent classes to inherit from non-persistent classes,
+ persistent classes to inherit from other persistent classes,
+ and non-persistent classes to inherit from persistent classes.
+ It is even possible to form inheritance hierarchies in which
+ persistence skips generations. There are, however, a few
+ important limitations:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Persistent classes cannot inherit from certain
+ natively-implemented system classes such as
+ <classname>java.net.Socket</classname> and
+ <classname>java.lang.Thread</classname>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If a persistent class inherits from a non-persistent
+ class, the fields of the non-persistent superclass
+ cannot be persisted.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All classes in an inheritance tree must use the same
+ identity type. We cover entity identity in
+ <xref linkend="jpa_overview_pc_identity"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="jpa_overview_pc_restrict_fields">
+ <title>Persistent Fields</title>
+ <indexterm zone="jpa_overview_pc_restrict_fields">
+ <primary>persistent classes</primary>
+ <secondary>field restrictions</secondary>
+ <seealso>persistent fields</seealso>
+ </indexterm>
+ <indexterm>
+ <primary>field</primary>
+ <secondary>persistent</secondary>
+ <see>persistent fields</see>
+ </indexterm>
+ <indexterm zone="jpa_overview_pc_restrict_fields">
+ <primary>persistent fields</primary>
+ <secondary>restrictions on</secondary>
+ </indexterm>
+ <para>
+ JPA manages the state of all persistent fields.
+ Before you access persistent state, the JPA runtime
+ makes sure that it has been loaded from the datastore. When you
+ set a field, the runtime records that it has changed so that
+ the new value will be persisted. This allows you to treat the
+ field in exactly the same way you treat any other field - another
+ aspect of JPA's transparency.
+ </para>
+ <para>
+ JPA does not support static or final fields.
+ It does, however, include built-in support for most
+ common field types. These types can be roughly divided into three
+ categories: immutable types, mutable types, and relations.
+ </para>
+ <para><indexterm><primary>persistent fields</primary><secondary>immutable types</secondary></indexterm><indexterm><primary>immutable</primary><secondary>persistent field types</secondary></indexterm><emphasis>Immutable</emphasis> types, once created, cannot be
+ changed. The only way to alter a persistent field of an immutable
+ type is to assign a new value to the field. JPA
+ supports the following immutable types:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ All primitives (<classname>int, float, byte</classname>,
+ etc)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All primitive wrappers (<classname>java.lang.Integer,
+ java.lang.Float, java.lang.Byte</classname>, etc)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <classname>java.lang.String</classname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <classname>java.math.BigInteger</classname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <classname>java.math.BigDecimal</classname>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ JPA also supports <classname>byte[]</classname> and
+ <classname>char[]</classname> as immutable types. That is, you
+ can persist fields of these types, but you should not manipulate
+ individual array indexes without resetting the array into the
+ persistent field.
+ </para>
+<!-- ### EJB3 : Byte[], Character[] -->
+ <para><indexterm><primary>persistent fields</primary><secondary>mutable types</secondary><seealso>proxies</seealso></indexterm><indexterm><primary>mutable</primary><secondary>persistent field types</secondary><seealso>persistent fields</seealso><seealso>proxies</seealso></indexterm><indexterm><primary>persistent fields</primary><secondary>user-defined types</secondary></indexterm><indexterm><primary>user-defined</primary><secondary>persistent field types</secondary><seealso>persistent fields</seealso></indexterm>
+ Persistent fields of <emphasis>mutable</emphasis> types
+ can be altered without assigning the field a new value.
+ Mutable types can be modified directly through their own
+ methods. The JPA specification requires that
+ implementations support the following mutable field types:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <classname>java.util.Date</classname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <classname>java.util.Calendar</classname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <classname>java.sql.Date</classname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <classname>java.sql.Timestamp</classname>
+ </para>
+ </listitem>
+ <listitem>
+ <para>Enums</para>
+ </listitem>
+ <listitem>
+ <para>Entity types (relations between entities)</para>
+ </listitem>
+ <listitem>
+ <para>Embeddable types</para>
+ </listitem>
+ <listitem>
+ <para><classname>java.util.Collection</classname>s of entities
+ </para>
+ </listitem>
+ <listitem>
+ <para><classname>java.util.Set</classname>s of entities
+ </para>
+ </listitem>
+ <listitem>
+ <para><classname>java.util.List</classname>s of entities
+ </para>
+ </listitem>
+ <listitem>
+ <para><classname>java.util.Map</classname>s in which each entry
+ maps the value of one of an entity's fields to that entity.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Collection and map types may be parameterized.
+ </para>
+ <para><indexterm><primary>persistent fields</primary><secondary>of unknown types</secondary></indexterm><indexterm><primary>Object</primary><secondary>as persistent field type</secondary><seealso>persistent fields</seealso></indexterm>
+ Most JPA implementations also have support for
+ persisting serializable values as binary data in the datastore.
+ <xref linkend="jpa_overview_meta"/> has more information on
+ persisting serializable types.
+ </para>
+ <note>
+ <para>
+ OpenJPA also supports arrays, <classname>
+ java.lang.Number</classname>, <classname>
+ java.util.Locale</classname>, all JDK 1.2 <classname>
+ Set</classname>, <classname>List</classname>, and <classname>
+ Map</classname> types, collections and maps of immutable and
+ embedded as well as entity types, and many other mutable and
+ immutable field types. OpenJPA also allows you to plug in
+ support for custom types.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_pc_restrict_conclusion">
+ <title>Conclusions</title>
+ <para>
+ This section detailed all of the restrictions JPA
+ places on persistent classes. While it may seem like we presented
+ a lot of information, you will seldom find yourself hindered by
+ these restrictions in practice. Additionally, there are often ways
+ of using JPA's other features to circumvent any
+ limitations you run into.
+ <!-- ### EJBDOC : good transition when lifecycle listeners are
+ ### added back as next section
+ The next section explores a powerful JPA feature
+ that is particularly useful for this purpose.
+ -->
+ </para>
+ </section>
+ </section>
+ <section id="jpa_overview_pc_identity">
+ <title>Entity Identity</title>
+ <indexterm zone="jpa_overview_pc_identity">
+ <primary>JPA</primary>
+ <secondary>identity</secondary>
+ <seealso>identity</seealso>
+ </indexterm>
+ <indexterm>
+ <primary>entity identity</primary>
+ <see>identity</see>
+ </indexterm>
+ <indexterm zone="jpa_overview_pc_identity">
+ <primary>identity</primary>
+ <secondary>JPA</secondary>
+ </indexterm>
+ <para><indexterm><primary>identity</primary><secondary>numeric</secondary></indexterm><indexterm><primary>identity</primary><secondary>qualitative</secondary></indexterm><indexterm><primary>numeric identity</primary><seealso>identity</seealso></indexterm><indexterm><primary>qualitative identity</primary><seealso>identity</seealso></indexterm>
+ Java recognizes two forms of object identity: numeric identity and
+ qualitative identity. If two references are
+ <emphasis>numerically</emphasis> identical, then they refer to the
+ same JVM instance in memory. You can test for this using the
+ <literal>==</literal> operator. <emphasis>Qualitative</emphasis>
+ identity, on the other hand, relies on some user-defined criteria to
+ determine whether two objects are "equal". You test for qualitative
+ identity using the <methodname>equals</methodname> method. By default,
+ this method simply relies on numeric identity.
+ </para>
+ <para>
+ JPA introduces another form of object identity, called
+ <emphasis>entity identity</emphasis> or <emphasis>persistent
+ identity</emphasis>. Entity identity tests whether two persistent
+ objects represent the same state in the datastore.
+ </para>
+ <para><indexterm><primary>persistent fields</primary><secondary>id</secondary></indexterm><indexterm><primary>id</primary><secondary>fields</secondary><seealso>persistent fields</seealso></indexterm>
+ The entity identity of each persistent instance is encapsulated in its
+ <emphasis>identity field(s)</emphasis>. If two entities of the same
+ type have the same identity field values, then the two
+ entities represent the same state in the datastore. Each entity's
+ identity field values must be unique among all other entites of the
+ same type.
+ </para>
+ <para>
+ Identity fields must be primitives, primitive wrappers,
+ <classname>String</classname>s, <classname>Date</classname>s,
+ <classname>Timestamp</classname>s, or embeddable types. Notably, other
+ entities instances can <emphasis>not</emphasis> be used as identity
+ fields.
+ </para>
+ <note>
+ <para>
+ For legacy schemas with binary primary key columns, OpenJPA
+ also supports using identity fields of type
+ <classname>byte[]</classname>. When you use a <classname>byte[]
+ </classname> identity field, you must
+ create an identity class. Identity classes are covered below.
+ </para>
+ </note>
+ <warning>
+ <para>
+ Changing the fields of an embeddable instance while it is assigned
+ to an identity field has undefined results. Always treat
+ embeddable identity instances as immutable objects in your
+ applications.
+ </para>
+ </warning>
+ <para><indexterm><primary>identity</primary><secondary>uniqueness requirement</secondary></indexterm><indexterm><primary>uniquness requirement</primary><seealso>identity</seealso></indexterm>
+ If you are dealing with a single persistence context (see
+ <xref linkend="jpa_overview_emfactory_perscontext"/>),
+ then you do not have to compare identity fields to test
+ whether two entity references represent the same state in the
+ datastore. There is a much easier way: the
+ <literal>==</literal> operator. JPA requires that
+ each persistence context maintain only one JVM object to represent
+ each unique datastore record. Thus, entity identity is equivalent to
+ numeric identity within a persistence context. This is referred to as
+ the <emphasis>uniqueness requirement</emphasis>.
+ </para>
+ <para>
+ The uniqueness requirement is extremely important - without it, it
+ would be impossible to maintain data integrity. Think of what
+ could happen if two different objects in the same transaction
+ were allowed to represent the same persistent data. If you made
+ different modifications to each of these objects, which set of changes
+ should be written to the datastore? How would your application logic
+ handle seeing two different "versions" of the same data? Thanks to the
+ uniqueness requirement, these questions do not have to be answered.
+ </para>
+ <section id="jpa_overview_pc_identitycls">
+ <title>Identity Class</title>
+ <para><indexterm zone="jpa_overview_pc_identitycls"><primary>identity class</primary><seealso>identity</seealso></indexterm><indexterm zone="jpa_overview_pc_identitycls"><primary>identity</primary><secondary>class requirements</secondary></indexterm>
+ If your entity has only one identity field, you can use the value of
+ that field as the entity's identity object in all
+ <link linkend="jpa_overview_em"><classname>EntityManager
+ </classname></link> APIs. Otherwise, you must supply an identity
+ class to use for identity objects. Your identity
+ class must meet the following criteria:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>The class must be public.</para>
+ </listitem>
+ <listitem>
+ <para>The class must be serializable.</para>
+ </listitem>
+ <listitem>
+ <para>
+ The class must have a public no-args constructor.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The names of the non-static fields or properties of the
+ class must be the same as the names of the identity fields
+ or properties of the corresponding entity class, and the
+ types must be identical.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The <methodname>equals</methodname> and
+ <methodname>hashCode</methodname> methods of the class
+ must use the values of all fields or properties
+ corresponding to identity fields or properties in the
+ entity class.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ If the class is an inner class, it must be
+ <literal>static</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All entity classes related by inheritance must use the same
+ identity class, or else each entity class must have its
+ own identity class whose inheritance hierarchy mirrors the
+ inheritance hierarchy of the owning entity classes (see
+ <xref linkend="jpa_overview_pc_identity_hierarchy"/>).
+ </para>
+ </listitem>
+ </itemizedlist>
+ <note>
+ <para>
+ Though you may still create identity classes by
+ hand, OpenJPA provides the <classname>appidtool</classname>
+ to automatically generate proper identity classes
+ based on your identity fields. See
+ <xref linkend="ref_guide_pc_oid_application"/> of the
+ Reference Guide.
+ </para>
+ </note>
+ <example id="jpa_overview_pc_identity_appidcode">
+ <title>Identity Class</title>
+ <para>
+ This example illustrates a proper identity class for an entity
+ with multiple identity fields.
+ </para>
+ <programlisting format="linespecific">
+/**
+ * Persistent class using application identity.
+ */
+public class Magazine
+{
+ private String isbn; // identity field
+ private String title; // identity field
+
+ // rest of fields and methods omitted
+
+
+ /**
+ * Application identity class for Magazine.
+ */
+ public static class MagazineId
+ {
+ // each identity field in the Magazine class must have a
+ // corresponding field in the identity class
+ public String isbn;
+ public String title;
+
+ /**
+ * Equality must be implemented in terms of identity field
+ * equality, and must use instanceof rather than comparing
+ * classes directly (some JPA implementations may subclass the
+ * identity class).
+ */
+ public boolean equals (Object other)
+ {
+ if (other == this)
+ return true;
+ if (!(other instanceof MagazineId))
+ return false;
+
+ MagazineId mi = (MagazineId) other;
+ return (isbn == mi.isbn
+ || (isbn != null && isbn.equals (mi.isbn)))
+ && (title == mi.title
+ || (title != null && title.equals (mi.title)));
+ }
+
+ /**
+ * Hashcode must also depend on identity values.
+ */
+ public int hashCode ()
+ {
+ return ((isbn == null) ? 0 : isbn.hashCode ())
+ ^ ((title == null) ? 0 : title.hashCode ());
+ }
+
+ public String toString ()
+ {
+ return isbn + ":" + title;
+ }
+ }
+}
+</programlisting>
+ </example>
+ <section id="jpa_overview_pc_identity_hierarchy">
+ <title>Identity Hierarchies</title>
+ <indexterm zone="jpa_overview_pc_identity_hierarchy">
+ <primary>identity</primary>
+ <secondary>hierarchy</secondary>
+ </indexterm>
+ <mediaobject>
+ <imageobject>
+<!-- PNG image data, 320 x 267 (see README) -->
+ <imagedata fileref="img/appid-hierarchy.png" width="213px"/>
+ </imageobject>
+ </mediaobject>
+ <para>
+ An alternative to having a single identity
+ class for an entire inheritance hierarchy is to have
+ one identity class per level in the
+ inheritance hierarchy. The requirements for using
+ a hierarchy of identity classes are as follows:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The inheritance hierarchy of identity
+ classes must exactly mirror the hierarchy of the
+ persistent classes that they identify. In the example
+ pictured above, abstract class
+ <classname>Person</classname> is extended by abstract
+ class <classname>Employee</classname>, which is extended
+ by non-abstract class <classname>
+ FullTimeEmployee</classname>, which is extended by
+ non-abstract class <classname>Manager</classname>.
+ The corresponding identity classes, then, are
+ an abstract <classname>PersonId</classname> class,
+ extended by an abstract
+ <classname>EmployeeId</classname> class, extended by a
+ non-abstract <classname>FullTimeEmployeeId</classname>
+ class, extended by a non-abstract
+ <classname>ManagerId</classname> class.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Subclasses in the identity hierarchy
+ may define additional identity fields until
+ the hierarchy becomes non-abstract. In the
+ aforementioned example, <classname>Person</classname>
+ defines an identity field <literal>ssn</literal>,
+ <classname>Employee</classname> defines additional
+ identity field <literal>userName</literal>, and
+ <classname>FullTimeEmployee</classname> adds a final
+ identity field, <literal>empId</literal>.
+ However, <classname>Manager</classname> may not define
+ any additional identity fields, since it is a
+ subclass of a non-abstract class. The hierarchy of
+ identity classes, of course, must match the identity
+ field definitions of the persistent class hierarchy.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ It is not necessary for each abstract class to declare
+ identity fields. In the previous example, the
+ abstract <classname>Person</classname> and
+ <classname>Employee</classname> classes could declare
+ no identity fields, and the first concrete subclass
+ <classname>FullTimeEmployee</classname> could define
+ one or more identity fields.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ All subclasses of a concrete identity class must
+ be <methodname>equals</methodname> and <methodname>
+ hashCode</methodname>-compatible with the concrete
+ superclass. This means that in our example, a
+ <classname>ManagerId</classname> instance and a
+ <classname>FullTimeEmployeeId</classname> instance
+ with the same identity field values should have the
+ same hash code, and should compare equal to each other
+ using the <methodname>equals</methodname> method of
+ either one. In practice, this requirement reduces to
+ the following coding practices:
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ Use <literal>instanceof</literal> instead of
+ comparing <classname>Class</classname> objects
+ in the <methodname>equals</methodname> methods
+ of your identity classes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ An identity class that extends another
+ non-abstract identity class should not override
+ <methodname>equals</methodname> or
+ <methodname>hashCode</methodname>.
+ </para>
+ </listitem>
+ </orderedlist>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ </section>
+ <section id="jpa_overview_pc_callbacks">
+ <title>Lifecycle Callbacks</title>
+ <indexterm zone="jpa_overview_pc_callbacks">
+ <primary>lifecycle callbacks</primary>
+ </indexterm>
+ <indexterm zone="jpa_overview_pc_callbacks">
+ <primary>persistent classes</primary>
+ <secondary>lifecycle callbacks</secondary>
+ <seealso>lifecycle callbacks</seealso>
+ </indexterm>
+ <para>
+ It is often necessary to perform various actions at different stages
+ of a persistent object's lifecycle. JPA includes
+ a variety of callbacks methods for monitoring changes in the
+ lifecycle of your persistent objects. These callbacks can
+ be defined on the persistent classes themselves and
+ on non-persistent listener classes.
+ </para>
+ <section id="jpa_overview_pc_callbacks_methods">
+ <title>Callback Methods</title>
+ <indexterm zone="jpa_overview_pc_callbacks_methods">
+ <primary>lifecycle callbacks</primary>
+ <secondary>callback methods</secondary>
+ </indexterm>
+ <indexterm zone="jpa_overview_pc_callbacks_methods">
+ <primary>entity</primary>
+ <secondary>callback methods</secondary>
+ </indexterm>
+ <para>
+ Every persistence event has a corresponding callback method
+ marker. These markers are shared between persistent classes
+ and their listeners. You can use these markers to designate
+ a method for callback either by annotating that method or by
+ listing the method in the XML mapping file for a given class.
+ The lifecycle events and their corresponding method markers are:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><indexterm><primary>PrePersist</primary><seealso>lifecycle callbacks</seealso></indexterm><ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/PrePersist.html"><classname>PrePersist</classname></ulink>:
+ Methods marked with this annotation will be invoked
+ before an object is persisted. This could be used for
+ assigning primary key values to persistent objects.
+ This is equivalent to the XML element tag
+ <literal>pre-persist</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>PostPersist</primary><seealso>lifecycle callbacks</seealso></indexterm><ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/PostPersist.html"><classname>PostPersist</classname></ulink>:
+ Methods marked with this annotation will be invoked
+ after an object has transitioned to the persistent state.
+ You might want to use such methods to update a screen
+ after a new row is added. This is equivalent
+ to the XML element tag <literal>post-persist</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>PostLoad</primary><seealso>lifecycle callbacks</seealso></indexterm><ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/PostLoad.html"><classname>PostLoad</classname></ulink>:
+ Methods marked with this annotation will be invoked after
+ all eagerly fetched fields of your class have been
+ loaded from the datastore. No other persistent fields
+ can be accessed in this method. This is equivalent
+ to the XML element tag <literal>post-load</literal>.
+ </para>
+ <para><classname>PostLoad</classname> is often used to
+ initialize non-persistent fields whose values depend
+ on the values of persistent fields, such as a complex
+ datastructure.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>PreUpdate</primary><seealso>lifecycle callbacks</seealso></indexterm><ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/PreUpdate.html"><classname>PreUpdate</classname></ulink>:
+ Methods marked with this annotation will be invoked
+ just the persistent values in your objects are flushed
+ to the datastore. This is equivalent to the XML element tag
+ <literal>pre-update</literal>.
+ </para>
+ <para><classname>PreUpdate</classname> is the complement to
+ <classname>PostLoad</classname>. While methods marked
+ with <classname>PostLoad</classname> are most often used
+ to initialize non-persistent values from persistent data,
+ methods annotated with <classname>PreUpdate</classname>
+ is normally used to set persistent fields with information
+ cached in non-persistent data.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>PostUpdate</primary><seealso>lifecycle callbacks</seealso></indexterm><ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/PostUpdate.html"><classname>PostUpdate</classname></ulink>:
+ Methods marked with this annotation will be invoked
+ after changes to a given instance have been stored to the
+ datastore. This is useful for clearing stale data cached
+ at the application layer. This is equivalent to the
+ XML element tag <literal>post-update</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>PreRemove</primary><seealso>lifecycle callbacks</seealso></indexterm><ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/PreRemove.html"><classname>PreRemove</classname></ulink>:
+ Methods marked with this annotation will be invoked
+ before an object transactions to the deleted state.
+ Access to persistent fields is valid within this method.
+ You might use this method to cascade the deletion to
+ related objects based on complex criteria, or to
+ perform other cleanup. This is equivalent to the
+ XML element tag <literal>pre-remove</literal>.
+ </para>
+ </listitem>
+ <listitem>
+ <para><indexterm><primary>PostRemove</primary><seealso>lifecycle callbacks</seealso></indexterm><ulink url="http://java.sun.com/javaee/5/docs/api/javax/persistence/PostRemove.html"><classname>PostRemove</classname></ulink>:
+ Methods marked with this annotation will be invoked after
+ an object has been marked as to be deleted. This is
+ equivalent to the XML element tag
+ <literal>post-remove</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="jpa_overview_callbacks_using">
+ <title>Using Callback Methods</title>
+ <para>
+ When declaring callback methods on a persistent class,
+ any method may be used which takes no arguments and is not
+ shared with any property access fields. Multiple events
+ can be assigned to a single method as well.
+ </para>
+ <para>
+ Below is an example of how to declare callback methods
+ on persistent classes:
+ </para>
+ <programlisting format="linespecific">
+/**
+ * Example persistent class declaring our entity listener.
+ */
+@Entity
+public class Magazine
+{
+ @Transient
+ private byte[][] data;
+
+ @ManyToMany
+ private List<Photo> photos;
+
+ @PostLoad
+ public void convertPhotos ()
+ {
+ data = new byte[photos.size ()][];
+ for (int i = 0; i < photos.size (); i++)
+ data[i] = photos.get (i).toByteArray ();
+ }
+
+ @PreDelete
+ public void logMagazineDeletion ()
+ {
+ getLog ().debug ("deleting magazine containing" + photos.size ()
+ + " photos.");
+ }
+}
+
+</programlisting>
+ <para>
+ In an XML mapping file, we can define the same methods
+ without annotations:
+ </para>
+ <programlisting format="linespecific">
+<entity class="Magazine">
+ <pre-remove>logMagazineDeletion</pre-remove>
+ <post-load>convertPhotos</post-load>
+</entity>
+</programlisting>
+ <note>
+ <para>
+ We fully explore persistence metadata annotations and XML in
+ <xref linkend="jpa_overview_meta"/>.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_entity_listeners_using">
+ <title>Using Entity Listeners</title>
+ <para>
+ Mixing lifecycle event code into your persistent classes is not
+ always ideal. It is often more elegant to handle cross-cutting
+ lifecycle events in a non-persistent listener class.
+ JPA allows for this, requiring only that listener
+ classes have a public no-arg constructor. Like persistent
+ classes, your listener classes can consume any number of callbacks.
+ The callback methods must take in a single
+ <classname>java.lang.Object</classname> argument which
+ represents the persistent object that triggered the event.
+ </para>
+ <para>
+ Entities can enumerate listeners using the
+ <classname>EntityListeners</classname> annotation. This annotation
+ takes an array of listener classes as its value.
+ </para>
+ <para>
+ Below is an example of how to declare an entity and its
+ corresponding listener classes.
+ </para>
+ <programlisting format="linespecific">
+/**
+ * Example persistent class declaring our entity listener.
+ */
+@Entity
+@EntityListeners({ MagazineLogger.class, ... })
+public class Magazine
+{
+ // ... //
+}
+
+
+/**
+ * Example entity listener.
+ */
+public class MagazineLogger
+{
+ @PostPersist
+ public void logAddition (Object pc)
+ {
+ getLog ().debug ("Added new magazine:" + ((Magazine) pc).getTitle ());
+ }
+
+
+ @PreRemove
+ public void logDeletion (Object pc)
+ {
+ getLog ().debug ("Removing from circulation:" +
+ ((Magazine) pc).getTitle ());
+ }
+}
+</programlisting>
+ <para>
+ In XML, we define both the listeners and their callback
+ methods as so:
+ </para>
+ <programlisting format="linespecific">
+<entity class="Magazine">
+ <entity-listeners>
+ <entity-listener class="MagazineLogger">
+ <post-persist>logAddition</post-persist>
+ <pre-remove>logDeletion</pre-remove>
+ </entity-listener>
+ </entity-listeners>
+</entity>
+</programlisting>
+ </section>
+ <section id="jpa_overview_entity_listeners_exclude">
+ <title>Entity Listeners Hierarchy</title>
+ <indexterm zone="jpa_overview_entity_listeners_exclude">
+ <primary>lifecycle listeners</primary>
+ <secondary>hierarchy</secondary>
+ </indexterm>
+ <para>
+ Entity listener methods are invoked in a specific order when a
+ given event is fired. So-called <emphasis>default</emphasis>
+ listeners are invoked first: these are listeners
+ which have been defined in a package annotation or in the root
+ element of XML mapping files. Next, entity listeners are invoked
+ in the order of the inheritance hierarchy, with superclass listeners
+ being invoked before subclass listeners. Finally, if an entity has
+ multiple listeners for the same event, the listeners are invoked
+ in declaration order.
+ </para>
+ <para>
+ You can exclude default listeners and listeners defined in
+ superclasses from the invocation chain through the use of two
+ class-level annotations:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><classname>ExcludeDefaultListeners</classname>: This
+ annotation indicates that no default listeners will be
+ invoked for this class, or any of its subclasses. The XML
+ equivalent is the empty
+ <literal>exclude-default-listeners</literal> element.
+ </para>
+ </listitem>
+ <listitem>
+ <para><classname>ExcludeSuperclassListeners</classname>: This
+ annotation will cause OpenJPA to skip invoking any listeners
+ declared in superclasses. The XML equivalent is empty the
+ <literal>exclude-superclass-listeners</literal> element.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ </section>
+ <section id="jpa_overview_pc_conclusion">
+ <title>Conclusions</title>
+ <para>
+ This chapter covered everything you need to know to write persistent
+ class definitions in JPA. JPA
+ cannot use your persistent classes, however, until you complete one
+ additional step: you must define the persistence metadata. The next
+ chapter explores metadata in detail.
+ </para>
+ </section>
+ </chapter>
+<!-- author: Abe White -->
+ <chapter id="jpa_overview_meta">
+ <title>Metadata</title>
+ <indexterm zone="jpa_overview_meta">
+ <primary>metadata</primary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta">
+ <primary>JPA</primary>
+ <secondary>metadata</secondary>
+ <seealso>metadata</seealso>
+ </indexterm>
+ <para>
+ JPA requires that you accompany each persistent class with
+ persistence metadata. This metadata serves three primary purposes:
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>To identify persistent classes.</para>
+ </listitem>
+ <listitem>
+ <para>To override default JPA behavior.</para>
+ </listitem>
+ <listitem>
+ <para>
+ To provide the JPA implementation with information that
+ it cannot glean from simply reflecting on the persistent class.
+ </para>
+ </listitem>
+ </orderedlist>
+ <para><indexterm><primary>annotations</primary></indexterm>
+ Persistence metadata is specified using either the Java 5 annotations
+ defined in the <literal>javax.persistence</literal> package, XML
+ mapping files, or a mixture of both. In the latter case, XML declarations
+ override conflicting annotations. If you choose to use XML metadata, the
+ XML files must be available at development and runtime, and must be
+ discoverable via either of two strategies:
+ </para>
+ <orderedlist>
+ <listitem>
+ <para>
+ In a resource named <filename>orm.xml</filename> placed in
+ the <filename>META-INF</filename> directory of the classpath
+ or the jar archive containing your persistent classes.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Declared in your <link linkend="jpa_overview_persistence_xml"><filename>persistence.xml</filename></link> configuration file.
+ In this case, each XML metadata file must be
+ listed in a <literal>mapping-file</literal> element whose
+ content is either a path to the given file or a resource
+ location available to the class' class loader.
+ </para>
+ </listitem>
+ </orderedlist>
+ <para>
+ We describe the standard metadata annotations and XML equivalents throughout
+ this chapter. The full schema for XML mapping files is available in
+ <xref linkend="jpa_overview_meta_xml"/>.
+ JPA also standardizes relational mapping metadata and named
+ query metadata, which we discuss in <xref linkend="jpa_overview_mapping"/>
+ and <xref linkend="jpa_overview_query_named"/> respectively.
+ </para>
+ <note>
+ <para>
+ OpenJPA defines many useful annotations beyond the standard set. See
+ <xref linkend="ref_guide_meta_ejb"/> and
+ <xref linkend="ref_guide_meta_ext"/> in the Reference Guide for details.
+ <!-- ### EJB -->
+ There are currently no XML equivalents for these extension annotations.
+ </para>
+ </note>
+ <mediaobject>
+ <imageobject>
+<!-- PNG image data, 553 x 580 (see README) -->
+ <imagedata fileref="img/ejb3-meta-model.png" width="369"/>
+ </imageobject>
+ </mediaobject>
+ <para>
+ Through the course of this chapter, we will create the persistent object
+ model above.
+ </para>
+ <section id="jpa_overview_meta_class">
+ <title>Class Metadata</title>
+ <para>
+ The following metadata annotations and XML elements apply to persistent
+ class declarations.
+ </para>
+ <section id="jpa_overview_meta_entity">
+ <title>Entity</title>
+ <indexterm zone="jpa_overview_meta_entity">
+ <primary>Entity</primary>
+ <secondary>annotation</secondary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_entity">
+ <primary>metadata</primary>
+ <secondary>Entity</secondary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_entity">
+ <primary>annotations</primary>
+ <secondary>Entity</secondary>
+ </indexterm>
+ <para>
+ The <classname>Entity</classname> annotation denotes an entity
+ class. All entity classes must have this annotation. The
+ <classname>Entity</classname> annotation takes one optional
+ property:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>String name</literal>: Name used to refer to the
+ entity in queries. Must not be a reserved literal
+ in JPQL. Defaults to the unqualified name of the entity
+ class.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The equivalent XML element is <literal>entity</literal>. It has
+ the following attributes:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>class</literal>: The entity class. This attribute
+ is required.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>name</literal>: Named used to refer to the class in
+ queries. See the name property above.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>access</literal>: The access type to use for the
+ class. Must either be <literal>FIELD</literal> or
+ <literal>PROPERTY</literal>. For details on access
+ types, see <xref linkend="jpa_overview_meta_field"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <note>
+ <para>
+ OpenJPA uses a process called <emphasis>enhancement</emphasis> to
+ modify the bytecode of entities for transparent
+ lazy loading and immediate dirty tracking. See
+ <xref linkend="ref_guide_pc_enhance"/> in the Reference Guide
+ for details on enhancement.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_meta_idclass">
+ <title>Id Class</title>
+ <indexterm zone="jpa_overview_meta_idclass">
+ <primary>IdClass</primary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_idclass">
+ <primary>metadata</primary>
+ <secondary>IdClass</secondary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_idclass">
+ <primary>annotations</primary>
+ <secondary>IdClass</secondary>
+ </indexterm>
+ <para>
+ As we discussed in <xref linkend="jpa_overview_pc_identitycls"/>,
+ entities with multiple identity fields must use an <emphasis>
+ identity class</emphasis> to encapsulate their persistent identity.
+ The <classname>IdClass</classname> annotation specifies this class.
+ It accepts a single <classname>java.lang.Class</classname> value.
+ </para>
+ <para>
+ The equivalent XML element is <literal>id-class</literal>, which has
+ a single attribute:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>class</literal>: This required attribute lists
+ the class name for the identity class.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </section>
+ <section id="jpa_overview_meta_embeddablesuper">
+ <title>Mapped Superclass</title>
+ <indexterm zone="jpa_overview_meta_embeddablesuper">
+ <primary>MappedSuperclass</primary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_embeddablesuper">
+ <primary>metadata</primary>
+ <secondary>MappedSuperclass</secondary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_embeddablesuper">
+ <primary>annotations</primary>
+ <secondary>MappedSuperclass</secondary>
+ </indexterm>
+ <para>
+ A <emphasis>mapped superclass</emphasis> is a non-entity
+ class that can define persistent state and mapping information for
+ entity subclasses. Mapped superclasses are usually abstract.
+ Unlike true entities, you cannot query a mapped superclass,
+ pass a mapped superclass instance to any
+ <classname>EntityManager</classname> or <classname>Query</classname>
+ methods, or declare a persistent relation with a mapped
+ superclass target.
+ You denote a mapped superclass with the <classname>MappedSuperclass
+ </classname> marker annotation.
+ </para>
+ <para>
+ The equivalent XML element is <literal>mapped-superclass</literal>.
+ It expects the following attributes:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>class</literal>: The entity class. This attribute
+ is required.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>access</literal>: The access type to use for the
+ class. Must either be <literal>FIELD</literal> or
+ <literal>PROPERTY</literal>. For details on access
+ types, see <xref linkend="jpa_overview_meta_field"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <note>
+ <para>
+ OpenJPA allows you to query on mapped superclasses. A
+ query on a mapped superclass will return all matching
+ subclass instances. OpenJPA also allows you to declare relations
+ to mapped superclass types; however, you cannot query across
+ these relations.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_meta_embeddable">
+ <title>Embeddable</title>
+ <indexterm zone="jpa_overview_meta_embeddable">
+ <primary>Embeddable</primary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_embeddable">
+ <primary>metadata</primary>
+ <secondary>Embeddable</secondary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_embeddable">
+ <primary>annotations</primary>
+ <secondary>Embeddable</secondary>
+ </indexterm>
+ <para>
+ The <classname>Embeddable</classname> annotation designates an
+ embeddable persistent class. Embeddable instances are stored as
+ part of the record of their owning instance. All embeddable
+ classes must have this annotation.
+ </para>
+ <para>
+ A persistent class can either be an entity or an embeddable class,
+ but not both.
+ </para>
+ <para>
+ The equivalent XML element is <literal>embeddable</literal>.
+ It understands the following attributes:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>class</literal>: The entity class. This attribute
+ is required.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>access</literal>: The access type to use for the
+ class. Must either be <literal>FIELD</literal> or
+ <literal>PROPERTY</literal>. For details on access
+ types, see <xref linkend="jpa_overview_meta_field"/>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <note>
+ <para>
+ OpenJPA allows a persistent class to be both an entity and
+ an embeddable class. Instances of the class will act as
+ entites when persisted explicitly or assigned to non-embedded
+ fields of entities. Instances will act as embedded values
+ when assigned to embedded fields of entities.
+ </para>
+ <para>
+ To signal that a class is both an entity and an embeddable class
+ in OpenJPA, simply add both the <literal>@Entity</literal> and the
+ <literal>@Embeddable</literal> annotations to the class.
+ </para>
+ </note>
+ </section>
+ <section id="jpa_overview_meta_entity_listeners">
+ <title>EntityListeners</title>
+ <indexterm zone="jpa_overview_meta_entity_listeners">
+ <primary>EntityListeners</primary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_entity_listeners">
+ <primary>entity-listeners</primary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_entity_listeners">
+ <primary>metadata</primary>
+ <secondary>EntityListeners</secondary>
+ </indexterm>
+ <indexterm zone="jpa_overview_meta_entity_listeners">
+ <primary>annotations</primary>
+ <secondary>EntityListeners</secondary>
+ </indexterm>
+ <para>
+ An entity may list its lifecycle event listeners
+ in the <classname>EntityListeners</classname> annotation.
+ This value of this annotation is an array of the listener
+ <classname>Class</classname>es for the entity.
+ The equivalent XML element is <literal>entity-listeners</literal>.
+ For more details on entity listeners, see
+ <xref linkend="jpa_overview_pc_callbacks"/>.
+ </para>
+ </section>
+ <section id="jpa_overview_meta_classex">
+ <title>Example</title>
+ <para>
+ Here are the class declarations for our persistent object model,
+ annotated with the appropriate persistence metadata. Note that
+ <classname>Magazine</classname> declares an identity class, and
+ that <classname>Document</classname> and <classname>Address
+ </classname> are a mapped superclass and an embeddable class,
+ respectively. <classname>LifetimeSubscription</classname> and
+ <classname>TrialSubscription</classname> override the default
[... 31730 lines stripped ...]