blob: fc9314527c24e849ed06bdf7479eae5fd73a11fc [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<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="jpa"/>
<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="jpa">
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="jpa">
<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="jpa">
<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="jpa">
<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="jpa">
<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="jpa">
<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="jpa">
<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="jpa">
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="jpa">
<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="jpa">
<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="jpa">
<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>