| <html><head> |
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
| <title>2. Entity Identity</title><base href="display"><link rel="stylesheet" type="text/css" href="css/docbook.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="manual.html" title="Apache OpenJPA 2.4 User's Guide"><link rel="up" href="jpa_overview_pc.html" title="Chapter 4. Entity"><link rel="prev" href="jpa_overview_pc.html" title="Chapter 4. Entity"><link rel="next" href="jpa_overview_pc_callbacks.html" title="3. Lifecycle Callbacks"></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">2. |
| Entity Identity |
| </th></tr><tr><td width="20%" align="left"><a accesskey="p" href="jpa_overview_pc.html">Prev</a> </td><th width="60%" align="center">Chapter 4. |
| Entity |
| </th><td width="20%" align="right"> <a accesskey="n" href="jpa_overview_pc_callbacks.html">Next</a></td></tr></table><hr></div><div class="section" id="jpa_overview_pc_identity"><div class="titlepage"><div><div><h2 class="title" style="clear: both">2. |
| Entity Identity |
| </h2></div></div></div><div class="toc"><dl class="toc"><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></div> |
| |
| <a class="indexterm" name="d5e722"></a> |
| <a class="indexterm" name="d5e726"></a> |
| <a class="indexterm" name="d5e729"></a> |
| <p> |
| <a class="indexterm" name="d5e733"></a> |
| <a class="indexterm" name="d5e736"></a> |
| <a class="indexterm" name="d5e739"></a> |
| <a class="indexterm" name="d5e742"></a> |
| Java recognizes two forms of object identity: numeric identity and qualitative |
| identity. If two references are <span class="emphasis"><em>numerically</em></span> identical, then |
| they refer to the same JVM instance in memory. You can test for this using the |
| <code class="literal">==</code> operator. <span class="emphasis"><em>Qualitative</em></span> 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 <code class="methodname"> |
| equals</code> method. By default, this method simply relies on numeric |
| identity. |
| </p> |
| <p> |
| JPA introduces another form of object identity, called <span class="emphasis"><em>entity |
| identity</em></span> or <span class="emphasis"><em>persistent identity</em></span>. Entity |
| identity tests whether two persistent objects represent the same state in the |
| datastore. |
| </p> |
| <p> |
| <a class="indexterm" name="d5e753"></a> |
| <a class="indexterm" name="d5e756"></a> |
| The entity identity of each persistent instance is encapsulated in its |
| <span class="emphasis"><em>identity field(s)</em></span>. 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 entities of the same type. |
| </p> |
| <p> |
| Identity fields must be primitives, primitive wrappers, <code class="classname"> |
| String</code>s, <code class="classname">Date</code>s, <code class="classname"> |
| Timestamp</code>s, or embeddable types. |
| </p> |
| <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3> |
| <p> |
| OpenJPA supports entities as identity fields, as the Reference Guide discusses |
| in <a class="xref" href="ref_guide_pc_oid.html#ref_guide_pc_oid_entitypk" title="4.2. Entities as Identity Fields">Section 4.2, “ |
| Entities as Identity Fields |
| ”</a>. For legacy schemas with binary |
| primary key columns, OpenJPA also supports using identity fields of type |
| <code class="classname">byte[]</code>. When you use a <code class="classname">byte[]</code> |
| identity field, you must create an identity class. Identity classes are |
| covered below. |
| </p> |
| </div> |
| <div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3> |
| <p> |
| 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. |
| </p> |
| </div> |
| <p> |
| <a class="indexterm" name="d5e773"></a> |
| <a class="indexterm" name="d5e776"></a> |
| If you are dealing with a single persistence context (see |
| <a class="xref" href="jpa_overview_emfactory_perscontext.html" title="3. Persistence Context">Section 3, “ |
| Persistence Context |
| ”</a>), 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 <code class="literal">== |
| </code> 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 <span class="emphasis"><em>uniqueness requirement</em></span>. |
| </p> |
| <p> |
| 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. |
| </p> |
| <div class="section" id="jpa_overview_pc_identitycls"><div class="titlepage"><div><div><h3 class="title">2.1. |
| Identity Class |
| </h3></div></div></div><div class="toc"><dl class="toc"><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></div> |
| |
| <p> |
| <a class="indexterm" name="d5e786"></a> |
| <a class="indexterm" name="d5e789"></a> |
| If your entity has only one identity field, you can use the value of that field |
| as the entity's identity object in all <a class="link" href="jpa_overview_em.html" title="Chapter 8. EntityManager"> |
| <code class="classname">EntityManager</code></a> APIs. Otherwise, you must supply an |
| identity class to use for identity objects. Your identity class must meet the |
| following criteria: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> |
| <p> |
| The class must be public. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| The class must be serializable. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| The class must have a public no-args constructor. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| 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. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| The <code class="methodname">equals</code> and <code class="methodname">hashCode</code> |
| methods of the class must use the values of all fields or properties |
| corresponding to identity fields or properties in the entity class. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| If the class is an inner class, it must be <code class="literal">static</code>. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| 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 |
| <a class="xref" href="jpa_overview_pc_identity.html#jpa_overview_pc_identity_hierarchy" title="2.1.1. Identity Hierarchies">Section 2.1.1, “ |
| Identity Hierarchies |
| ”</a>). |
| </p> |
| </li></ul></div> |
| <div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3> |
| <p> |
| Though you may still create identity classes by hand, OpenJPA provides the |
| <code class="classname">appidtool</code> to automatically generate proper identity |
| classes based on your identity fields. See |
| <a class="xref" href="ref_guide_pc_oid.html#ref_guide_pc_oid_application" title="4.3. Application Identity Tool">Section 4.3, “ |
| Application Identity Tool |
| ”</a> of the Reference Guide. |
| </p> |
| </div> |
| <div class="example" id="jpa_overview_pc_identity_appidcode"><p class="title"><b>Example 4.2. |
| Identity Class |
| </b></p><div class="example-contents"> |
| |
| <p> |
| This example illustrates a proper identity class for an entity with multiple |
| identity fields. |
| </p> |
| <pre class="programlisting"> |
| /** |
| * 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; |
| } |
| } |
| } |
| </pre> |
| </div></div><br class="example-break"> |
| <div class="section" id="jpa_overview_pc_identity_hierarchy"><div class="titlepage"><div><div><h4 class="title">2.1.1. |
| Identity Hierarchies |
| </h4></div></div></div> |
| |
| <a class="indexterm" name="d5e823"></a> |
| <div class="mediaobject"><table border="0" summary="manufactured viewport for HTML img" style="cellpadding: 0; cellspacing: 0;" width="213"><tr><td><img src="img/appid-hierarchy.png"></td></tr></table></div> |
| <p> |
| 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: |
| </p> |
| <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> |
| <p> |
| 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 <code class="classname">Person</code> is extended by abstract class |
| <code class="classname">Employee</code>, which is extended by non-abstract class |
| <code class="classname"> FullTimeEmployee</code>, which is extended by non-abstract |
| class <code class="classname">Manager</code>. The corresponding identity classes, then, |
| are an abstract <code class="classname">PersonId</code> class, extended by an abstract |
| <code class="classname">EmployeeId</code> class, extended by a non-abstract <code class="classname"> |
| FullTimeEmployeeId</code> class, extended by a non-abstract <code class="classname"> |
| ManagerId</code> class. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| Subclasses in the identity hierarchy may define additional identity fields until |
| the hierarchy becomes non-abstract. In the aforementioned example, <code class="classname"> |
| Person</code> defines an identity field <code class="literal">ssn</code>, <code class="classname"> |
| Employee</code> defines additional identity field <code class="literal">userName |
| </code>, and <code class="classname">FullTimeEmployee</code> adds a final identity |
| field, <code class="literal">empId</code>. However, <code class="classname">Manager</code> 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. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| It is not necessary for each abstract class to declare identity fields. In the |
| previous example, the abstract <code class="classname">Person</code> and <code class="classname"> |
| Employee</code> classes could declare no identity fields, and the first |
| concrete subclass <code class="classname">FullTimeEmployee</code> could define one or |
| more identity fields. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| All subclasses of a concrete identity class must be <code class="methodname">equals |
| </code> and <code class="methodname">hashCode</code>-compatible with the |
| concrete superclass. This means that in our example, a <code class="classname">ManagerId |
| </code> instance and a <code class="classname">FullTimeEmployeeId</code> instance |
| with the same identity field values should have the same hash code, and should |
| compare equal to each other using the <code class="methodname">equals</code> method of |
| either one. In practice, this requirement reduces to the following coding |
| practices: |
| </p> |
| <div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"> |
| <p> |
| Use <code class="literal">instanceof</code> instead of comparing <code class="classname">Class |
| </code> objects in the <code class="methodname">equals</code> methods of your |
| identity classes. |
| </p> |
| </li><li class="listitem"> |
| <p> |
| An identity class that extends another non-abstract identity class should not |
| override <code class="methodname">equals</code> or <code class="methodname">hashCode</code>. |
| </p> |
| </li></ol></div> |
| </li></ul></div> |
| </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_pc.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="jpa_overview_pc.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="jpa_overview_pc_callbacks.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 4. |
| Entity |
| </td><td width="20%" align="center"><a accesskey="h" href="manual.html">Home</a></td><td width="40%" align="right" valign="top"> 3. |
| Lifecycle Callbacks |
| </td></tr></table></div></body></html> |