blob: 6b0438f077ffc7f59c5132fd50c5f4ebc139cf7a [file] [log] [blame]
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter&nbsp;4.&nbsp; Entity</title><link rel="stylesheet" href="css/docbook.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.72.0"><link rel="start" href="manual.html" title="Apache OpenJPA User's Guide"><link rel="up" href="jpa_overview.html" title="Part&nbsp;2.&nbsp;Java Persistence API"><link rel="prev" href="jpa_overview_arch.html" title="Chapter&nbsp;3.&nbsp; Java Persistence API Architecture"><link rel="next" href="jpa_overview_pc_identity.html" title="2.&nbsp; Entity Identity"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter&nbsp;4.&nbsp;
Entity
</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="jpa_overview_arch.html">Prev</a>&nbsp;</td><th width="60%" align="center">Part&nbsp;2.&nbsp;Java Persistence API</th><td width="20%" align="right">&nbsp;<a accesskey="n" href="jpa_overview_pc_identity.html">Next</a></td></tr></table><hr></div><div class="chapter" lang="en" id="jpa_overview_pc"><div class="titlepage"><div><div><h2 class="title"><a name="jpa_overview_pc"></a>Chapter&nbsp;4.&nbsp;
Entity
</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_restrict">1.
Restrictions on Persistent Classes
</a></span></dt><dd><dl><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_no_arg">1.1.
Default or No-Arg Constructor
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_final">1.2.
Final
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_id">1.3.
Identity Fields
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_version">1.4.
Version Field
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_restrict_inheritance">1.5.
Inheritance
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_restrict_fields">1.6.
Persistent Fields
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_restrict_conclusion">1.7.
Conclusions
</a></span></dt></dl></dd><dt><span class="section"><a href="jpa_overview_pc_identity.html">2.
Entity Identity
</a></span></dt><dd><dl><dt><span class="section"><a href="jpa_overview_pc_identity.html#jpa_overview_pc_identitycls">2.1.
Identity Class
</a></span></dt><dd><dl><dt><span class="section"><a href="jpa_overview_pc_identity.html#jpa_overview_pc_identity_hierarchy">2.1.1.
Identity Hierarchies
</a></span></dt></dl></dd></dl></dd><dt><span class="section"><a href="jpa_overview_pc_callbacks.html">3.
Lifecycle Callbacks
</a></span></dt><dd><dl><dt><span class="section"><a href="jpa_overview_pc_callbacks.html#jpa_overview_pc_callbacks_methods">3.1.
Callback Methods
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc_callbacks.html#jpa_overview_callbacks_using">3.2.
Using Callback Methods
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc_callbacks.html#jpa_overview_entity_listeners_using">3.3.
Using Entity Listeners
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc_callbacks.html#jpa_overview_entity_listeners_exclude">3.4.
Entity Listeners Hierarchy
</a></span></dt></dl></dd><dt><span class="section"><a href="jpa_overview_pc_conclusion.html">4.
Conclusions
</a></span></dt></dl></div><a class="indexterm" name="d0e835"></a><a class="indexterm" name="d0e838"></a><a class="indexterm" name="d0e843"></a><a class="indexterm" name="d0e850"></a><p>
JPA recognizes two types of persistent classes: <span class="emphasis"><em>entity</em></span>
classes and <span class="emphasis"><em>embeddable</em></span> classes. Each persistent instance of
an entity class - each <span class="emphasis"><em>entity</em></span> - represents a unique
datastore record. You can use the <code class="classname">EntityManager</code> to find
an entity by its persistent identity (covered later in this chapter), or use a
<code class="classname">Query</code> to find entities matching certain criteria.
</p><p>
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 <code class="classname">EntityManager</code> or from a
<code class="classname">Query</code> unless the query uses a projection on owning class
to the embedded instance. For example, if <code class="classname">Address</code> is
embedded in <code class="classname">Company</code>, then
a query <code class="classname">"SELECT a FROM Address a"</code> will never return the
embedded <code class="classname">Address</code> of <code class="classname">Company</code>;
but a projection query such as
<code class="classname">"SELECT c.address FROM Company c"</code> will.
</p><p>
Despite these differences, there are few distinctions between entity classes and
embeddable classes. In fact, writing either type of persistent class is a lot
like 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.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
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.
</p></div><div class="example"><a name="jpa_overview_pc_pcclass"></a><p class="title"><b>Example&nbsp;4.1.&nbsp;
Persistent Class
</b></p><div class="example-contents"><pre class="programlisting">
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
}
</pre></div></div><br class="example-break"><div class="section" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="jpa_overview_pc_restrict"></a>1.&nbsp;
Restrictions on Persistent Classes
</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_no_arg">1.1.
Default or No-Arg Constructor
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_final">1.2.
Final
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_id">1.3.
Identity Fields
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_version">1.4.
Version Field
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_restrict_inheritance">1.5.
Inheritance
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_restrict_fields">1.6.
Persistent Fields
</a></span></dt><dt><span class="section"><a href="jpa_overview_pc.html#jpa_overview_pc_restrict_conclusion">1.7.
Conclusions
</a></span></dt></dl></div><a class="indexterm" name="d0e911"></a><p>
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.
</p><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_pc_no_arg"></a>1.1.&nbsp;
Default or No-Arg Constructor
</h3></div></div></div><a class="indexterm" name="d0e921"></a><a class="indexterm" name="d0e926"></a><p>
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.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
OpenJPA's <span class="emphasis"><em>enhancer</em></span> will automatically add a protected
no-arg constructor to your class when required. Therefore, this restriction does
not apply when using the enhancer. See <a href="ref_guide_pc_enhance.html" title="2.&nbsp; Enhancement">Section&nbsp;2, &#8220;
Enhancement
&#8221;</a>
of the Reference Guide for details.
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_pc_final"></a>1.2.&nbsp;
Final
</h3></div></div></div><p>
Entity classes may not be final. No method of an entity class can be final.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
OpenJPA supports final classes and final methods.
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_pc_id"></a>1.3.&nbsp;
Identity Fields
</h3></div></div></div><a class="indexterm" name="d0e952"></a><a class="indexterm" name="d0e957"></a><p>
All entity classes must declare one or more fields which together form the
persistent identity of an instance. These are called <span class="emphasis"><em>identity
</em></span> or <span class="emphasis"><em>primary key</em></span> fields. In our <code class="classname">
Magazine</code> class, <code class="literal">isbn</code> and <code class="literal">title</code>
are identity fields, because no two magazine records in the datastore can have
the same <code class="literal">isbn</code> and <code class="literal">title</code> values.
<a href="jpa_overview_meta_field.html#jpa_overview_meta_id" title="2.2.&nbsp; Id">Section&nbsp;2.2, &#8220;
Id
&#8221;</a> will show you how to denote your
identity fields in JPA metadata. <a href="jpa_overview_pc_identity.html" title="2.&nbsp; Entity Identity">Section&nbsp;2, &#8220;
Entity Identity
&#8221;</a>
below examines persistent identity.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
OpenJPA fully supports identity fields, but does not require them. See
<a href="ref_guide_pc_oid.html" title="4.&nbsp; Object Identity">Section&nbsp;4, &#8220;
Object Identity
&#8221;</a> of the Reference Guide for details.
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_pc_version"></a>1.4.&nbsp;
Version Field
</h3></div></div></div><a class="indexterm" name="d0e997"></a><a class="indexterm" name="d0e1002"></a><p>
The <code class="literal">version</code> field in our <code class="classname">Magazine</code>
class may seem out of place. JPA uses a version field in your entities 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.
</p><p>
A 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.
<a href="jpa_overview_meta_field.html#jpa_overview_meta_version" title="2.5.&nbsp; Version">Section&nbsp;2.5, &#8220;
Version
&#8221;</a> shows you how to designate a
version field in JPA metadata.
</p><p>
The version field must be an integral type (<code class="classname"> int</code>,
<code class="classname">Long</code>, etc) or a <code class="classname">
java.sql.Timestamp</code>. You should consider version fields immutable.
Changing the field value has undefined results.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
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
<a href="ref_guide_mapping_jpa.html" title="7.&nbsp; Additional JPA Mappings">Section&nbsp;7, &#8220;
Additional JPA Mappings
&#8221;</a> in the Reference Guide.
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_pc_restrict_inheritance"></a>1.5.&nbsp;
Inheritance
</h3></div></div></div><a class="indexterm" name="d0e1038"></a><a class="indexterm" name="d0e1045"></a><p>
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:
</p><div class="itemizedlist"><ul type="disc"><li><p>
Persistent classes cannot inherit from certain natively-implemented system
classes such as <code class="classname">java.net.Socket</code> and <code class="classname">
java.lang.Thread</code>.
</p></li><li><p>
If a persistent class inherits from a non-persistent class, the fields of the
non-persistent superclass cannot be persisted.
</p></li><li><p>
All classes in an inheritance tree must use the same identity type. We cover
entity identity in <a href="jpa_overview_pc_identity.html" title="2.&nbsp; Entity Identity">Section&nbsp;2, &#8220;
Entity Identity
&#8221;</a>.
</p></li></ul></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_pc_restrict_fields"></a>1.6.&nbsp;
Persistent Fields
</h3></div></div></div><a class="indexterm" name="d0e1073"></a><a class="indexterm" name="d0e1080"></a><a class="indexterm" name="d0e1087"></a><p>
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.
</p><p>
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.
</p><p>
<a class="indexterm" name="d0e1098"></a>
<a class="indexterm" name="d0e1104"></a>
<span class="emphasis"><em>Immutable</em></span> 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:
</p><div class="itemizedlist"><ul type="disc"><li><p>
All primitives (<code class="classname">int, float, byte</code>, etc)
</p></li><li><p>
All primitive wrappers (<code class="classname">java.lang.Integer, java.lang.Float,
java.lang.Byte</code>, etc)
</p></li><li><p>
<code class="classname">java.lang.String</code>
</p></li><li><p>
<code class="classname">java.math.BigInteger</code>
</p></li><li><p>
<code class="classname">java.math.BigDecimal</code>
</p></li></ul></div><p>
JPA also supports <code class="classname">byte[]</code>, <code class="classname">Byte[]</code>,
<code class="classname">char[]</code>, and <code class="classname">Character[]</code> 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.
</p><p>
<a class="indexterm" name="d0e1160"></a>
<a class="indexterm" name="d0e1168"></a>
<a class="indexterm" name="d0e1178"></a>
<a class="indexterm" name="d0e1184"></a>
Persistent fields of <span class="emphasis"><em>mutable</em></span> 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:
</p><div class="itemizedlist"><ul type="disc"><li><p>
<code class="classname">java.util.Date</code>
</p></li><li><p>
<code class="classname">java.util.Calendar</code>
</p></li><li><p>
<code class="classname">java.sql.Date</code>
</p></li><li><p>
<code class="classname">java.sql.Timestamp</code>
</p></li><li><p>
<code class="classname">java.sql.Time</code>
</p></li><li><p>
Enums
</p></li><li><p>
Entity types (relations between entities)
</p></li><li><p>
Embeddable types
</p></li><li><p>
<code class="classname">java.util.Collection</code>s of entities
</p></li><li><p>
<code class="classname">java.util.Set</code>s of entities
</p></li><li><p>
<code class="classname">java.util.List</code>s of entities
</p></li><li><p>
<code class="classname">java.util.Map</code>s in which each entry maps the value of one
of a related entity's fields to that entity.
</p></li></ul></div><p>
Collection and map types may be parameterized.
</p><p>
<a class="indexterm" name="d0e1263"></a>
<a class="indexterm" name="d0e1269"></a>
Most JPA implementations also have support for persisting serializable values as
binary data in the datastore. <a href="jpa_overview_meta.html" title="Chapter&nbsp;5.&nbsp; Metadata">Chapter&nbsp;5, <i xmlns:xlink="http://www.w3.org/1999/xlink">
Metadata
</i></a> has more
information on persisting serializable types.
</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>
OpenJPA also supports arrays, <code class="classname">java.lang.Number</code>,
<code class="classname">java.util.Locale</code>, all JDK 1.2 <code class="classname">Set</code>,
<code class="classname">List</code>, and <code class="classname">Map</code> types,
and many other mutable and immutable field types. OpenJPA also allows you to
plug in support for custom types.
</p></div></div><div class="section" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="jpa_overview_pc_restrict_conclusion"></a>1.7.&nbsp;
Conclusions
</h3></div></div></div><p>
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.
</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="jpa_overview_arch.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a accesskey="u" href="jpa_overview.html">Up</a></td><td width="40%" align="right">&nbsp;<a accesskey="n" href="jpa_overview_pc_identity.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter&nbsp;3.&nbsp;
Java Persistence API Architecture
&nbsp;</td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top">&nbsp;2.&nbsp;
Entity Identity
</td></tr></table></div></body></html>