[hibernate-commits] Hibernate SVN: r19978 - core/trunk/documentation/manual/src/main/docbook/en-US/content.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jul 20 20:58:11 EDT 2010


Author: steve.ebersole at jboss.com
Date: 2010-07-20 20:58:10 -0400 (Tue, 20 Jul 2010)
New Revision: 19978

Modified:
   core/trunk/documentation/manual/src/main/docbook/en-US/content/persistent_classes.xml
Log:
HHH-5397 - Odds and ends from documentation merge : persistent_classes.xml


Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/persistent_classes.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/persistent_classes.xml	2010-07-20 12:45:55 UTC (rev 19977)
+++ core/trunk/documentation/manual/src/main/docbook/en-US/content/persistent_classes.xml	2010-07-21 00:58:10 UTC (rev 19978)
@@ -2,10 +2,10 @@
 <!--
   ~ Hibernate, Relational Persistence for Idiomatic Java
   ~
-  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+  ~ Copyright (c) 2010, Red Hat Inc. or third-party contributors as
   ~ indicated by the @author tags or express copyright attribution
   ~ statements applied by the authors.  All third-party contributions are
-  ~ distributed under license by Red Hat Middleware LLC.
+  ~ distributed under license by Red Hat Inc.
   ~
   ~ This copyrighted material is made available to anyone wishing to use, modify,
   ~ copy, or redistribute it subject to the terms and conditions of the GNU
@@ -27,39 +27,40 @@
 <!ENTITY % BOOK_ENTITIES SYSTEM "../HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.ent">
 %BOOK_ENTITIES;
 ]>
-<chapter id="persistent-classes" revision="2">
-  <title>Persistent Classes</title>
 
-  <para>Persistent classes are classes in an application that implement the
-  entities of the business problem (e.g. Customer and Order in an E-commerce
-  application). Not all instances of a persistent class are considered to be
-  in the persistent state. For example, an instance can instead be transient
-  or detached.</para>
+<chapter id="persistent-classes">
+    <title>Persistent Classes</title>
 
-  <para>Hibernate works best if these classes follow some simple rules, also
-  known as the Plain Old Java Object (POJO) programming model. However, none
-  of these rules are hard requirements. Indeed, Hibernate3 assumes very little
-  about the nature of your persistent objects. You can express a domain model
-  in other ways (using trees of <literal>Map</literal> instances, for
-  example).</para>
+    <para>
+        Persistent classes are classes in an application that implement the entities of the business problem
+        (e.g. Customer and Order in an E-commerce application).  The term "persistent" here means that the classes
+        are able to be persisted, not that they are in the persistent state (see <xref linkend="objectstate-overview"/>
+        for discussion).
+    </para>
 
-  <section id="persistent-classes-pojo">
-    <title>A simple POJO example</title>
+    <para>
+        Hibernate works best if these classes follow some simple rules, also known as the Plain Old Java Object (POJO)
+        programming model. However, none of these rules are hard requirements. Indeed, Hibernate assumes very little
+        about the nature of your persistent objects. You can express a domain model in other ways (using trees of
+        <interfacename>java.util.Map</interfacename> instances, for example).
+    </para>
 
-    <para>Most Java applications require a persistent class representing
-    felines. For example:</para>
+    <section id="persistent-classes-pojo">
+        <title>A simple POJO example</title>
 
-    <programlisting role="JAVA">package eg;
+        <example id="persistent-classes-pojo-example-cat">
+            <title>Simple POJO representing a cat</title>
+            <programlisting role="JAVA">package eg;
 import java.util.Set;
 import java.util.Date;
 
 public class Cat {
-    private Long id; // identifier
+private Long id; // identifier
 
-    private Date birthdate;
-    private Color color;
-    private char sex;
-    private float weight;
+private Date birthdate;
+private Color color;
+private char sex;
+private float weight;
     private int litterId;
 
     private Cat mother;
@@ -119,107 +120,136 @@
     public Set getKittens() {
         return kittens;
     }
-    
+
     // addKitten not needed by Hibernate
     public void addKitten(Cat kitten) {
-    	kitten.setMother(this);
-	kitten.setLitterId( kittens.size() ); 
+        kitten.setMother(this);
+    kitten.setLitterId( kittens.size() );
         kittens.add(kitten);
     }
 }</programlisting>
+        </example>
 
-    <para>The four main rules of persistent classes are explored in more
-    detail in the following sections.</para>
 
-    <section id="persistent-classes-pojo-constructor" revision="1">
-      <title>Implement a no-argument constructor</title>
+        <para>
+            The four main rules of persistent classes are explored in more detail in the following sections.
+        </para>
 
-      <para><literal>Cat</literal> has a no-argument constructor. All
-      persistent classes must have a default constructor (which can be
-      non-public) so that Hibernate can instantiate them using
-      <literal>Constructor.newInstance()</literal>. It is recommended that you
-      have a default constructor with at least <emphasis>package</emphasis>
-      visibility for runtime proxy generation in Hibernate.</para>
-    </section>
+        <section id="persistent-classes-pojo-constructor">
+            <title>Implement a no-argument constructor</title>
 
-    <section id="persistent-classes-pojo-identifier" revision="2">
-      <title>Provide an identifier property (optional)</title>
+            <para>
+                <classname>Cat</classname> has a no-argument constructor. All persistent classes must have a default
+                constructor (which can be non-public) so that Hibernate can instantiate them using
+                <literal><classname>java.lang.reflect.Constructor</classname>.newInstance()</literal>.  It is recommended
+                that this constructor be defined with at least <emphasis>package</emphasis> visibility in order for
+                runtime proxy generation to work properly.
+            </para>
+        </section>
 
-      <para><literal>Cat</literal> has a property called
-      <literal>id</literal>. This property maps to the primary key column of a
-      database table. The property might have been called anything, and its
-      type might have been any primitive type, any primitive "wrapper" type,
-      <literal>java.lang.String</literal> or
-      <literal>java.util.Date</literal>. If your legacy database table has
-      composite keys, you can use a user-defined class with properties of
-      these types (see the section on composite identifiers later in the
-      chapter.)</para>
+        <section id="persistent-classes-pojo-identifier" revision="2">
+          <title>Provide an identifier property</title>
 
-      <para>The identifier property is strictly optional. You can leave them
-      off and let Hibernate keep track of object identifiers internally. We do
-      not recommend this, however.</para>
+            <note>
+                <para>
+                    Historically this was considered option.  While still not (yet) enforced, this should be considered
+                    a deprecated feature as it will be completely required to provide a identifier property in an
+                    upcoming release.
+                </para>
+            </note>
 
-      <para>In fact, some functionality is available only to classes that
-      declare an identifier property:</para>
+            <para>
+                <classname>Cat</classname> has a property named <literal>id</literal>.  This property maps to the
+                primary key column(s) of the underlying database table.  The type of the identifier property can
+                be any "basic" type (see <xref linkend="types.value.basic"/>).  See <xref linkend="components-compositeid"/>
+                for information on mapping composite (multi-column) identifiers.
+            </para>
 
-      <itemizedlist spacing="compact">
-        <listitem>
-          <para>Transitive reattachment for detached objects (cascade update
-          or cascade merge) - see <xref
-          linkend="objectstate-transitive" /></para>
-        </listitem>
+            <note>
+                <para>
+                    Identifiers do not necessarily need to identify column(s) in the database physically defined
+                    as a primary key.  They should just identify columns that can be used to uniquely identify rows
+                    in the underlying table.
+                </para>
+            </note>
 
-        <listitem>
-          <para><literal>Session.saveOrUpdate()</literal></para>
-        </listitem>
+            <para>
+                We recommend that you declare consistently-named identifier properties on persistent classes and that you use
+                a nullable (i.e., non-primitive) type.
+            </para>
+        </section>
 
-        <listitem>
-          <para><literal>Session.merge()</literal></para>
-        </listitem>
-      </itemizedlist>
 
-      <para>We recommend that you declare consistently-named identifier
-      properties on persistent classes and that you use a nullable (i.e.,
-      non-primitive) type.</para>
-    </section>
+        <section id="persistent-classes-pojo-final">
+            <title>Prefer non-final classes (semi-optional)</title>
 
-    <section id="persistent-classes-pojo-final">
-      <title>Prefer non-final classes (optional)</title>
+            <para>
+                A central feature of Hibernate, <emphasis>proxies</emphasis> (lazy loading), depends upon the
+                persistent class being either non-final, or the implementation of an interface that declares all public
+                methods.  You can persist <literal>final</literal> classes that do not implement an interface with
+                Hibernate; you will not, however, be able to use proxies for lazy association fetching which will
+                ultimately limit your options for performance tuning.  To persist a <literal>final</literal>
+                class which does not implement a "full" interface you must disable proxy generation.  See
+                <xref linkend="persistent-classes-pojo-final-example-disable-proxies-xml"/> and
+                <xref linkend="persistent-classes-pojo-final-example-disable-proxies-ann"/>.
+            </para>
 
-      <para>A central feature of Hibernate, <emphasis>proxies</emphasis>,
-      depends upon the persistent class being either non-final, or the
-      implementation of an interface that declares all public methods.</para>
+            <example id="persistent-classes-pojo-final-example-disable-proxies-xml">
+                <title>Disabling proxies in <literal>hbm.xml</literal></title>
+                <programlisting role="XML"><![CDATA[<class name="Cat" lazy="false"...>...</class>]]></programlisting>
+            </example>
 
-      <para>You can persist <literal>final</literal> classes that do not
-      implement an interface with Hibernate. You will not, however, be able to
-      use proxies for lazy association fetching which will ultimately limit
-      your options for performance tuning.</para>
+            <example id="persistent-classes-pojo-final-example-disable-proxies-ann">
+                <title>Disabling proxies in annotations</title>
+                <programlisting role="JAVA"><![CDATA[@Entity @Proxy(lazy=false) public class Cat { ... }]]></programlisting>
+            </example>
 
-      <para>You should also avoid declaring <literal>public final</literal>
-      methods on the non-final classes. If you want to use a class with a
-      <literal>public final</literal> method, you must explicitly disable
-      proxying by setting <literal>lazy="false"</literal>.</para>
-    </section>
+            <para>
+                If the <literal>final</literal> class does implement a proper interface, you could alternatively tell
+                Hibernate to use the interface instead when generating the proxies.  See
+                <xref linkend="persistent-classes-pojo-final-example-proxy-interface-xml"/> and
+                <xref linkend="persistent-classes-pojo-final-example-proxy-interface-ann"/>.
 
-    <section id="persistent-classes-pojo-accessors" revision="2">
-      <title>Declare accessors and mutators for persistent fields
-      (optional)</title>
+            </para>
 
-      <para><literal>Cat</literal> declares accessor methods for all its
-      persistent fields. Many other ORM tools directly persist instance
-      variables. It is better to provide an indirection between the relational
-      schema and internal data structures of the class. By default, Hibernate
-      persists JavaBeans style properties and recognizes method names of the
-      form <literal>getFoo</literal>, <literal>isFoo</literal> and
-      <literal>setFoo</literal>. If required, you can switch to direct field
-      access for particular properties.</para>
+            <example id="persistent-classes-pojo-final-example-proxy-interface-xml">
+                <title>Proxying an interface in <literal>hbm.xml</literal></title>
+                <programlisting role="XML"><![CDATA[<class name="Cat" proxy="ICat"...>...</class>]]></programlisting>
+            </example>
 
-      <para>Properties need <emphasis>not</emphasis> be declared public -
-      Hibernate can persist a property with a default,
-      <literal>protected</literal> or <literal>private</literal> get / set
-      pair.</para>
+            <example id="persistent-classes-pojo-final-example-proxy-interface-ann">
+                <title>Proxying an interface in annotations</title>
+                <programlisting role="JAVA"><![CDATA[@Entity @Proxy(proxyClass=ICat.class) public class Cat implements ICat { ... }]]></programlisting>
+            </example>
+
+            <para>
+                You should also avoid declaring <literal>public final</literal> methods as this will again limit
+                the ability to generate <emphasis>proxies</emphasis> from this class.  If you want to use a
+                class with <literal>public final</literal> methods, you must explicitly disable proxying.  Again, see
+                <xref linkend="persistent-classes-pojo-final-example-disable-proxies-xml"/> and
+                <xref linkend="persistent-classes-pojo-final-example-disable-proxies-ann"/>.
+            </para>
+        </section>
+
+        <section id="persistent-classes-pojo-accessors">
+            <title>Declare accessors and mutators for persistent fields (optional)</title>
+
+            <para>
+                <classname>Cat</classname> declares accessor methods for all its persistent fields. Many other ORM
+                tools directly persist instance variables. It is better to provide an indirection between the relational
+                schema and internal data structures of the class. By default, Hibernate persists JavaBeans style
+                properties and recognizes method names of the form <literal>getFoo</literal>, <literal>isFoo</literal>
+                and <literal>setFoo</literal>.  If required, you can switch to direct field access for particular
+                properties.
+            </para>
+
+            <para>
+                Properties need <emphasis>not</emphasis> be declared public.  Hibernate can persist a property declared
+                with <literal>package</literal>, <literal>protected</literal> or <literal>private</literal> visibility
+                as well.
+            </para>
+        </section>
     </section>
-  </section>
 
   <section id="persistent-classes-inheritance">
     <title>Implementing inheritance</title>
@@ -447,44 +477,53 @@
     found in <xref linkend="xml" />.</para>
   </section>
 
-  <section id="persistent-classes-tuplizers" revision="1">
-    <title>Tuplizers</title>
 
-    <para><literal>org.hibernate.tuple.Tuplizer</literal>, and its
-    sub-interfaces, are responsible for managing a particular representation
-    of a piece of data given that representation's
-    <literal>org.hibernate.EntityMode</literal>. If a given piece of data is
-    thought of as a data structure, then a tuplizer is the thing that knows
-    how to create such a data structure and how to extract values from and
-    inject values into such a data structure. For example, for the POJO entity
-    mode, the corresponding tuplizer knows how create the POJO through its
-    constructor. It also knows how to access the POJO properties using the
-    defined property accessors.</para>
+    <section id="persistent-classes-tuplizers" revision="1">
+        <title>Tuplizers</title>
 
-    <para>There are two high-level types of Tuplizers, represented by the
-    <literal>org.hibernate.tuple.entity.EntityTuplizer</literal> and
-    <literal>org.hibernate.tuple.component.ComponentTuplizer</literal>
-    interfaces. <literal>EntityTuplizer</literal>s are responsible for
-    managing the above mentioned contracts in regards to entities, while
-    <literal>ComponentTuplizer</literal>s do the same for components.</para>
+        <para>
+            <interfacename>org.hibernate.tuple.Tuplizer</interfacename> and its sub-interfaces are responsible for
+            managing a particular representation of a piece of data given that representation's
+            <classname>org.hibernate.EntityMode</classname>.  If a given piece of data is thought of as a data
+            structure, then a tuplizer is the thing that knows how to create such a data structure, how to extract
+            values from such a data structure and how to inject values into such a data structure.  For example, for
+            the POJO entity mode, the corresponding tuplizer knows how create the POJO through its constructor.
+            It also knows how to access the POJO properties using the defined property accessors.
+        </para>
 
-    <para>Users can also plug in their own tuplizers. Perhaps you require that
-    a <literal>java.util.Map</literal> implementation other than
-    <literal>java.util.HashMap</literal> be used while in the dynamic-map
-    entity-mode. Or perhaps you need to define a different proxy generation
-    strategy than the one used by default. Both would be achieved by defining
-    a custom tuplizer implementation. Tuplizer definitions are attached to the
-    entity or component mapping they are meant to manage. Going back to the
-    example of our customer entity <xref
-    linkend="example-defining-tuplizer-using-annotations" /> shows how to
-    configure tuplizers using annotations whereas <xref
-    linkend="example-defining-tuplizer-using-mapping-file" /> shows how to do
-    the same thing using Hibernate mapping files.</para>
+        <para>
+            There are two (high-level) types of Tuplizers:
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <interfacename>org.hibernate.tuple.entity.EntityTuplizer</interfacename> which is
+                        responsible for managing the above mentioned contracts in regards to entities
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        <interfacename>org.hibernate.tuple.component.ComponentTuplizer</interfacename> which does the
+                        same for components
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </para>
 
-    <example id="example-defining-tuplizer-using-annotations">
-      <title>Mapping custom tuplizers using annotations</title>
+        <para>
+            Users can also plug in their own tuplizers. Perhaps you require that
+            <interfacename>java.util.Map</interfacename> implementation other than
+            <classname>java.util.HashMap</classname> be used while in the dynamic-map entity-mode.  Or perhaps you
+            need to define a different proxy generation strategy than the one used by default.  Both would be achieved
+            by defining a custom tuplizer implementation.  Tuplizer definitions are attached to the entity or component
+            mapping they are meant to manage.  Going back to the example of our <classname>Customer</classname> entity,
+            <xref linkend="example-specify-custom-tuplizer-ann"/> shows how to specify a custom
+            <interfacename>org.hibernate.tuple.entity.EntityTuplizer</interfacename> using annotations while
+            <xref linkend="example-specify-custom-tuplizer-xml"/> shows how to do the same in <literal>hbm.xml</literal>
+        </para>
 
-      <programlisting role="XML">@Entity
+        <example id="example-specify-custom-tuplizer-ann">
+            <title>Specify custom tuplizers in annotations</title>
+<programlisting role="JAVA">@Entity
 @Tuplizer(impl = DynamicEntityTuplizer.class)
 public interface Cuisine {
     @Id
@@ -499,13 +538,10 @@
     public Country getCountry();
     public void setCountry(Country country);
 }</programlisting>
-    </example>
-
-    <example>
-      <title id="example-defining-tuplizer-using-mapping-file">Mapping custom
-      tuplizers using mapping files</title>
-
-      <programlisting role="XML">&lt;hibernate-mapping&gt;
+        </example>
+        <example id="example-specify-custom-tuplizer-xml">
+            <title>Specify custom tuplizers in <literal>hbm.xml</literal></title>
+<programlisting role="XML">&lt;hibernate-mapping&gt;
     &lt;class entity-name="Customer"&gt;
         &lt;!--
             Override the dynamic-map entity-mode
@@ -521,33 +557,29 @@
         &lt;!-- other properties --&gt;
         ...
     &lt;/class&gt;
-&lt;/hibernate-mapping&gt;
-</programlisting>
-    </example>
-  </section>
+&lt;/hibernate-mapping&gt;</programlisting>
+        </example>
+    </section>
 
-  <section id="persistent-classes-entity-name-resolver" revision="0">
-    <title>EntityNameResolvers</title>
+    <section id="persistent-classes-entity-name-resolver">
+        <title>EntityNameResolvers</title>
 
-    <para>The <interfacename>org.hibernate.EntityNameResolver</interfacename>
-    interface is a contract for resolving the entity name of a given entity
-    instance. The interface defines a single method
-    <methodname>resolveEntityName</methodname> which is passed the entity
-    instance and is expected to return the appropriate entity name (null is
-    allowed and would indicate that the resolver does not know how to resolve
-    the entity name of the given entity instance). Generally speaking, an
-    <interfacename>org.hibernate.EntityNameResolver</interfacename> is going
-    to be most useful in the case of dynamic models. One example might be
-    using proxied interfaces as your domain model. The hibernate test suite
-    has an example of this exact style of usage under the
-    <package>org.hibernate.test.dynamicentity.tuplizer2</package>. Here is
-    some of the code from that package for illustration.</para>
+        <para>
+            <interfacename>org.hibernate.EntityNameResolver</interfacename> is a contract for resolving the entity name
+            of a given entity instance. The interface defines a single method <methodname>resolveEntityName</methodname>
+            which is passed the entity instance and is expected to return the appropriate entity name (null is
+            allowed and would indicate that the resolver does not know how to resolve the entity name of the given entity
+            instance). Generally speaking, an <interfacename>org.hibernate.EntityNameResolver</interfacename> is going
+            to be most useful in the case of dynamic models. One example might be using proxied interfaces as your
+            domain model. The hibernate test suite has an example of this exact style of usage under the
+            <package>org.hibernate.test.dynamicentity.tuplizer2</package>. Here is some of the code from that package
+            for illustration.
+        </para>
 
-    <programlisting role="JAVA">
-/**
- * A very trivial JDK Proxy InvocationHandler implementation where we proxy an interface as
- * the domain model and simply store persistent state in an internal Map.  This is an extremely
- * trivial example meant only for illustration.
+<programlisting role="JAVA">/**
+ * A very trivial JDK Proxy InvocationHandler implementation where we proxy an
+ * interface as the domain model and simply store persistent state in an internal
+ * Map.  This is an extremely trivial example meant only for illustration.
  */
 public final class DataProxyHandler implements InvocationHandler {
 	private String entityName;
@@ -586,9 +618,6 @@
 	}
 }
 
-/**
- *
- */
 public class ProxyHelper {
     public static String extractEntityName(Object object) {
         // Our custom java.lang.reflect.Proxy instances actually bundle
@@ -610,12 +639,14 @@
 
 /**
  * The EntityNameResolver implementation.
- * IMPL NOTE : An EntityNameResolver really defines a strategy for how entity names should be
- * resolved.  Since this particular impl can handle resolution for all of our entities we want to
- * take advantage of the fact that SessionFactoryImpl keeps these in a Set so that we only ever
- * have one instance registered.  Why?  Well, when it comes time to resolve an entity name,
- * Hibernate must iterate over all the registered resolvers.  So keeping that number down
- * helps that process be as speedy as possible.  Hence the equals and hashCode impls
+ *
+ * IMPL NOTE : An EntityNameResolver really defines a strategy for how entity names
+ * should be resolved.  Since this particular impl can handle resolution for all of our
+ * entities we want to take advantage of the fact that SessionFactoryImpl keeps these
+ * in a Set so that we only ever have one instance registered.  Why?  Well, when it
+ * comes time to resolve an entity name, Hibernate must iterate over all the registered
+ * resolvers.  So keeping that number down helps that process be as speedy as possible.
+ * Hence the equals and hashCode implementations as is
  */
 public class MyEntityNameResolver implements EntityNameResolver {
     public static final MyEntityNameResolver INSTANCE = new MyEntityNameResolver();
@@ -651,26 +682,26 @@
     }
 
     ...
-}
-        </programlisting>
+</programlisting>
 
-    <para>In order to register an
-    <interfacename>org.hibernate.EntityNameResolver</interfacename> users must
-    either: <orderedlist>
-        <listitem>
-          <para>Implement a custom <link
-          linkend="persistent-classes-tuplizers">Tuplizer</link>, implementing
-          the <methodname>getEntityNameResolvers</methodname> method.</para>
-        </listitem>
+        <para>
+            In order to register an <interfacename>org.hibernate.EntityNameResolver</interfacename> users must either:
+            <orderedlist>
+                <listitem>
+                    <para>
+                        Implement a custom tuplizer (see <xref linkend="persistent-classes-tuplizers"/>), implementing
+                        the <methodname>getEntityNameResolvers</methodname> method
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Register it with the <classname>org.hibernate.impl.SessionFactoryImpl</classname> (which is the
+                        implementation class for <interfacename>org.hibernate.SessionFactory</interfacename>) using the
+                        <methodname>registerEntityNameResolver</methodname> method.
+                    </para>
+                </listitem>
+            </orderedlist>
+        </para>
+    </section>
 
-        <listitem>
-          <para>Register it with the
-          <classname>org.hibernate.impl.SessionFactoryImpl</classname> (which
-          is the implementation class for
-          <interfacename>org.hibernate.SessionFactory</interfacename>) using
-          the <methodname>registerEntityNameResolver</methodname>
-          method.</para>
-        </listitem>
-      </orderedlist></para>
-  </section>
 </chapter>



More information about the hibernate-commits mailing list