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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue May 25 15:07:44 EDT 2010


Author: steve.ebersole at jboss.com
Date: 2010-05-25 15:07:43 -0400 (Tue, 25 May 2010)
New Revision: 19607

Added:
   core/trunk/documentation/manual/src/main/docbook/en-US/content/type.xml
Log:


Added: core/trunk/documentation/manual/src/main/docbook/en-US/content/type.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/type.xml	                        (rev 0)
+++ core/trunk/documentation/manual/src/main/docbook/en-US/content/type.xml	2010-05-25 19:07:43 UTC (rev 19607)
@@ -0,0 +1,990 @@
+<!--
+  ~ Hibernate, Relational Persistence for Idiomatic Java
+  ~
+  ~ 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 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
+  ~ Lesser General Public License, as published by the Free Software Foundation.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+  ~ for more details.
+  ~
+  ~ You should have received a copy of the GNU Lesser General Public License
+  ~ along with this distribution; if not, write to:
+  ~ Free Software Foundation, Inc.
+  ~ 51 Franklin Street, Fifth Floor
+  ~ Boston, MA  02110-1301  USA
+  -->
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+        
+<chapter id="types">
+    <title>Types</title>
+
+    <para>
+        As an Object/Relational Mapping solution, Hibernate deals with both the Java and JDBC representations of
+        application data.  An online catalog application, for example, most likely has <classname>Product</classname>
+        object with a number of attributes such as a <literal>sku</literal>, <literal>name</literal>, etc.  For these
+        individual attributes, Hibernate must be able to read the values out of the database and write them back.  This
+        'marshalling' is the function of a <emphasis>Hibernate type</emphasis>, which is an implementation of the
+        <interfacename>org.hibernate.type.Type</interfacename> interface.  In addition, a
+        <emphasis>Hibernate type</emphasis> describes various aspects of behavior of the Java type such as "how is
+        equality checked?" or "how are values cloned?".
+    </para>
+
+    <important>
+        <para>
+            A Hibernate type is neither a Java type nor a SQL datatype; it provides a information about both.
+        </para>
+        <para>
+            When you encounter the term <emphasis>type</emphasis> in regards to Hibernate be aware that usage might
+            refer to the Java type, the SQL/JDBC type or the Hibernate type.
+        </para>
+    </important>
+
+    <para>
+        Hibernate categorizes types into two high-level groups: value types (see <xref linkend="types.value"/>) and
+        entity types (see <xref linkend="types.entity"/>).
+    </para>
+
+    <section id="types.value">
+        <title>Value types</title>
+
+        <para>
+            The main distinguishing characteristic of a value type is the fact that they do not define their own
+            lifecycle.  We say that they are "owned" by something else (specifically an entity, as we will see later)
+            which defines their lifecycle.  Value types are further classified into 3 sub-categories: basic types (see
+            <xref linkend="types.value.basic"/>), composite types (see <xref linkend="types.value.composite"/>)
+            amd collection types (see <xref linkend="types.value.collection"/>).
+        </para>
+
+        <section id="types.value.basic">
+            <title>Basic value types</title>
+            <para>
+                The norm for basic value types is that they map a single database value (column) to a single, 
+                non-aggregated Java type.  Hibernate provides a number of built-in basic types, which we will present
+                in the following sections by the Java type.  Mainly these follow the natural mappings recommended in the
+                JDBC specification.  We will later cover how to override these mapping and how to provide and use
+                alternative type mappings.
+            </para>
+            <section id="types.value.basic.string">
+                <title>java.lang.String</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.StringType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a string to the JDBC VARCHAR type.  This is the standard mapping for a string if 
+                                no Hibernate type is specified.
+                            </para>
+                            <para>
+                                Registered under <literal>string</literal> and <literal>java.lang.String</literal>
+                                in the type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.MaterializedClob</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a string to a JDBC CLOB type
+                            </para>
+                            <para>
+                                Registered under <literal>materialized_clob</literal> in the type registry (see
+                                <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.TextType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a string to a JDBC LONGVARCHAR type
+                            </para>
+                            <para>
+                                Registered under <literal>text</literal> in the type registry (see
+                                <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.character">
+                <title><classname>java.lang.Character</classname> (or char primitive)</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.CharacterType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a char or <classname>java.lang.Character</classname> to a JDBC CHAR
+                            </para>
+                            <para>
+                                Registered under <literal>char</literal> and <literal>java.lang.Character</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.value.basic.boolean">
+                <title><classname>java.lang.Boolean</classname> (or boolean primitive)</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.BooleanType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a boolean to a JDBC BIT type
+                            </para>
+                            <para>
+                                Registered under <literal>boolean</literal> and <literal>java.lang.Boolean</literal> in
+                                the type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.NumericBooleanType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a boolean to a JDBC INTEGER type as 0 = false, 1 = true
+                            </para>
+                            <para>
+                                Registered under <literal>numeric_boolean</literal> in the type registry (see
+                                <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.YesNoType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a boolean to a JDBC CHAR type as ('N' | 'n') = false, ( 'Y' | 'y' ) = true
+                            </para>
+                            <para>
+                                Registered under <literal>yes_no</literal> in the type registry (see
+                                <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.TrueFalseType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a boolean to a JDBC CHAR type as ('F' | 'f') = false, ( 'T' | 't' ) = true
+                            </para>
+                            <para>
+                                Registered under <literal>true_false</literal> in the type registry (see
+                                <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.byte">
+                <title><classname>java.lang.Byte</classname> (or byte primitive)</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.ByteType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a byte or <classname>java.lang.Byte</classname> to a JDBC TINYINT
+                            </para>
+                            <para>
+                                Registered under <literal>byte</literal> and <literal>java.lang.Byte</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.short">
+                <title><classname>java.lang.Short</classname> (or short primitive)</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.ShortType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a short or <classname>java.lang.Short</classname> to a JDBC SMALLINT
+                            </para>
+                            <para>
+                                Registered under <literal>short</literal> and <literal>java.lang.Short</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.int">
+                <title><classname>java.lang.Integer</classname> (or int primitive)</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.IntegerTypes</classname></term>
+                        <listitem>
+                            <para>
+                                Maps an int or <classname>java.lang.Integer</classname> to a JDBC INTEGER
+                            </para>
+                            <para>
+                                Registered under <literal>int</literal> and <literal>java.lang.Integer</literal>in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.long">
+                <title><classname>java.lang.Long</classname> (or long primitive)</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.LongType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a long or <classname>java.lang.Long</classname> to a JDBC BIGINT
+                            </para>
+                            <para>
+                                Registered under <literal>long</literal> and <literal>java.lang.Long</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.float">
+                <title><classname>java.lang.Float</classname> (or float primitive)</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.FloatType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a float or <classname>java.lang.Float</classname> to a JDBC FLOAT
+                            </para>
+                            <para>
+                                Registered under <literal>float</literal> and <literal>java.lang.Float</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.double">
+                <title><classname>java.lang.Double</classname> (or double primitive)</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.DoubleType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a double or <classname>java.lang.Double</classname> to a JDBC DOUBLE
+                            </para>
+                            <para>
+                                Registered under <literal>double</literal> and <literal>java.lang.Double</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.biginteger">
+                <title><classname>java.math.BigInteger</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.BigIntegerType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.math.BigInteger</classname> to a JDBC NUMERIC
+                            </para>
+                            <para>
+                                Registered under <literal>big_integer</literal> and <literal>java.math.BigInteger</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.bigdecimal">
+                <title><classname>java.math.BigDecimal</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.BigDecimalType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.math.BigDecimal</classname> to a JDBC NUMERIC
+                            </para>
+                            <para>
+                                Registered under <literal>big_decimal</literal> and <literal>java.math.BigDecimal</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.timestamp">
+                <title><classname>java.util.Date</classname> or <classname>java.sql.Timestamp</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.TimestampType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.sql.Timestamp</classname> to a JDBC TIMESTAMP
+                            </para>
+                            <para>
+                                Registered under <literal>timestamp</literal>, <literal>java.sql.Timestamp</literal> and
+                                <literal>java.util.Date</literal> in the type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.time">
+                <title><classname>java.sql.Time</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.TimeType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.sql.Time</classname> to a JDBC TIME
+                            </para>
+                            <para>
+                                Registered under <literal>time</literal> and <literal>java.sql.Time</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.date">
+                <title><classname>java.sql.Date</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.DateType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.sql.Date</classname> to a JDBC DATE
+                            </para>
+                            <para>
+                                Registered under <literal>date</literal> and <literal>java.sql.Date</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.calendar">
+                <title><classname>java.util.Calendar</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.CalendarType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.util.Calendar</classname> to a JDBC TIMESTAMP
+                            </para>
+                            <para>
+                                Registered under <literal>calendar</literal>, <literal>java.util.Calendar</literal> and
+                                <literal>java.util.GregorianCalendar</literal> in the type registry (see
+                                <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.CalendarDateType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.util.Calendar</classname> to a JDBC DATE
+                            </para>
+                            <para>
+                                Registered under <literal>calendar_date</literal> in the type registry (see
+                                <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.currency">
+                <title><classname>java.util.Currency</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.CurrencyType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.util.Currency</classname> to a JDBC VARCHAR (using the Currency code)
+                            </para>
+                            <para>
+                                Registered under <literal>currency</literal> and <literal>java.util.Currency</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.locale">
+                <title><classname>java.util.Locale</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.LocaleType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.util.Locale</classname> to a JDBC VARCHAR (using the Locale code)
+                            </para>
+                            <para>
+                                Registered under <literal>locale</literal> and <literal>java.util.Locale</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.timezone">
+                <title><classname>java.util.TimeZone</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.TimeZoneType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.util.TimeZone</classname> to a JDBC VARCHAR (using the TimeZone ID)
+                            </para>
+                            <para>
+                                Registered under <literal>timezone</literal> and <literal>java.util.TimeZone</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.class">
+                <title><classname>java.lang.Class</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.ClassType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.lang.Class</classname> to a JDBC VARCHAR (using the Class name)
+                            </para>
+                            <para>
+                                Registered under <literal>class</literal> and <literal>java.lang.Class</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.blob">
+                <title><classname>java.sql.Blob</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.BlobType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.sql.Blob</classname> to a JDBC BLOB
+                            </para>
+                            <para>
+                                Registered under <literal>blob</literal> and <literal>java.sql.Blob</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.clob">
+                <title><classname>java.sql.Clob</classname></title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.ClobType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a <classname>java.sql.Clob</classname> to a JDBC CLOB
+                            </para>
+                            <para>
+                                Registered under <literal>clob</literal> and <literal>java.sql.Clob</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.binary">
+                <title>byte[]</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.BinaryType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a primitive byte[] to a JDBC VARBINARY
+                            </para>
+                            <para>
+                                Registered under <literal>binary</literal> and <literal>byte[]</literal> in the
+                                type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.MaterializedBlobType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a primitive byte[] to a JDBC BLOB
+                            </para>
+                            <para>
+                                Registered under <literal>materialized_blob</literal> in the type registry (see
+                                <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.wrapperbinary">
+                <title>byte[]</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.BinaryType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a java.lang.Byte[] to a JDBC VARBINARY
+                            </para>
+                            <para>
+                                Registered under <literal>wrapper-binary</literal>, <literal>Byte[]</literal> and
+                                <literal>java.lang.Byte[]</literal> in the type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.chararray">
+                <title>char[]</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.CharArrayType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a char[] to a JDBC VARCHAR
+                            </para>
+                            <para>
+                                Registered under <literal>characters</literal> and <literal>char[]</literal>
+                                in the type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.characterarray">
+                <title>char[]</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.CharacterArrayType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps a java.lang.Character[] to a JDBC VARCHAR
+                            </para>
+                            <para>
+                                Registered under <literal>wrapper-characters</literal>, <literal>Character[]</literal>
+                                and <literal>java.lang.Character[]</literal> in the type registry (see <xref linkend="types.registry"/>).
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+            <section id="types.basic.value.serializable">
+                <title>java.io.Serializable</title>
+                <variablelist>
+                    <varlistentry>
+                        <term><classname>org.hibernate.type.SerializableType</classname></term>
+                        <listitem>
+                            <para>
+                                Maps implementors of java.lang.Serializable to a JDBC VARBINARY
+                            </para>
+                            <para>
+                                Unlike the other value types, there are multiple instances of this type.  It
+                                gets registered once under <literal>java.io.Serializable</literal>.  Additionally it
+                                gets registered under the specific <interfacename>java.io.Serializable</interfacename>
+                                implementation class names.
+                            </para>
+                        </listitem>
+                    </varlistentry>
+                </variablelist>
+            </section>
+        </section>
+
+        <section id="types.value.composite">
+            <title>Composite types</title>
+            <note>
+                <para>
+                    The Java Persistence API calls these embedded types, while Hibernate traditionally called them
+                    components.  Just be aware that both terms are used and mean the same thing in the scope of
+                    discussing Hibernate.
+                </para>
+            </note>
+            <para>
+                Components represent aggregations of values into a single Java type.  For example, you might have
+                an Address class that aggregates street, city, state, etc information or a Name class that
+                aggregates the parts of a person's Name.  In many ways a component looks exactly like an entity.  They
+                are both (generally speaking) classes written specifically for the application.  They both might have
+                references to other application-specific classes, as well as to collections and simple JDK types.  As
+                discussed before, the only distinguishing factory is the fact that a component does not own its own
+                lifecycle.
+            </para>
+        </section>
+
+        <section id="types.value.collection">
+            <title>Collection types</title>
+            <important>
+                <para>
+                    It is critical understand that we mean the collection itself, not its contents.
+                    The contents of the collection can in turn be basic, component or entity types (though not
+                    collections), but the collection itself is owned.
+                </para>
+            </important>
+            <para>
+                Collections are covered in <xref linkend="collections"/>.
+            </para>
+        </section>
+
+    </section>
+
+    <section id="types.entity">
+        <title>Entity types</title>
+        <para>
+            The definition of entities is covered in detail in <xref linkend="persistent-classes"/>.  For the purpose of
+            this discussion, it is enough to say that entities are (generally application-specific) classes which
+            correlate to rows in a table.  Specifically they correlate to the row by means of a unique identifier.
+            Because of this unique identifier, entities exist independently and define their own lifecycle.  As an example,
+            when we delete a <classname>Membership</classname>, both the <classname>User</classname> and
+            <classname>Group</classname> entities remain.
+            <note>
+                <para>
+                    This notion of entity independence can be modified by the application developer using the concept of
+                    cascades.  Cascades allow certain operations to continue (or "cascade") across an association from
+                    one entity to another.  Cascades are covered in detail in <xref linkend="associations"/>.
+                </para>
+            </note>
+        </para>
+    </section>
+
+    <section id="types.category.significance">
+        <title>Significance of type categories</title>
+        <para>
+            Why do we spend so much time categorizing the various types of types?  What is the significance of the
+            distinction?
+        </para>
+        <para>
+            The main categorization was between entity types and value types.  To review we said that entities, by
+            nature of their unique identifier, exist independently of other objects whereas values do not.  An
+            application cannot "delete" a Product sku; instead, the sku is removed when the Product itself is
+            deleted (obviously you can <emphasis>update</emphasis> the sku of that Product to null to maker it
+            "go away", but even there the access is done through the Product).
+        </para>
+        <para>
+            Nor can you define an association <emphasis>to</emphasis> that Product sku.  You <emphasis>can</emphasis>
+            define an association to Product <emphasis>based on</emphasis> its sku, assuming sku is unique but that
+            is totally different.
+
+
+            entity types define
+            data that maintains its own lifecycle, while value types define data that only exists dependently.  Essentially it defines it own unique identifier.  In turn that means
+            that it can be used to share references to that data from other entities (or components or collections).
+            This dependence/independence has a few important ramifications:
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        First, entities can be looked up and referenced (as in foreign keys).  The same is not true of
+                        a value type.  For example, a <classname>Product</classname> entity can be looked up by its
+                        unique identifier.  The sku of that Product
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </para>
+    </section>
+
+    <section id="types.custom">
+        <title>Custom types</title>
+        <para>
+            Hibernate makes it relatively easy for developers to create their own <emphasis>value</emphasis> types.  For
+            example, you might want to persist properties of type <classname>java.lang.BigInteger</classname> to
+            <literal>VARCHAR</literal> columns.  Custom types are not limited to mapping values to a single table
+            column.  So, for example, you might want to concatenate together <literal>FIRST_NAME</literal>,
+            <literal>INITIAL</literal> and <literal>SURNAME</literal> columsn into a <classname>java,lang.String</classname>.
+        </para>
+
+        <para>
+            There are 3 approaches to developing a custom Hibernate type.  As a means of illustrating the different
+            approaches, lets consider a use case where we need to compose a <classname>java.math.BigDecimal</classname>
+            and <classname>java.util.Currency</classname> together into a custom <classname>Money</classname> class.
+        </para>
+
+        <section id="types.custom.type">
+            <title>Custom types using <interfacename>org.hibernate.type.Type</interfacename></title>
+            <para>
+                The first approach is to directly implement the <interfacename>org.hibernate.type.Type</interfacename>
+                interface (or one of its derivatives).  Probably, you will be more interested in the more specific
+                <interfacename>org.hibernate.type.BasicType</interfacename> contract which would allow registration of
+                the type (see <xref linkend="types.registry"/>).  The benefit of this registration is that whenever
+                the metadata for a particular property does not specify the Hibernate type to use, Hibernate will
+                consult the registry for the exposed property type.  In our example, the property type would be
+                <classname>Money</classname>, which is the key we would use to register our type in the registry:
+                <example id="types.custom.type.ex.definition">
+                    <title>Defining and registering the custom Type</title>
+                    <programlisting role="JAVA"><![CDATA[public class MoneyType implements BasicType {
+    public String[] getRegistrationKeys() {
+        return new String[] { Money.class.getName() };
+    }
+
+	public int[] sqlTypes(Mapping mapping) {
+	    // We will simply use delegation to the standard basic types for BigDecimal and Currency for many of the
+	    // Type methods...
+	    return new int[] {
+	             BigDecimalType.INSTANCE.sqlType(),
+	             CurrencyType.INSTANCE.sqlType(),
+	    };
+	    // we could also have honored any registry overrides via...
+	    //return new int[] {
+	    //         mappings.getTypeResolver().basic( BigDecimal.class.getName() ).sqlTypes( mappings )[0],
+	    //         mappings.getTypeResolver().basic( Currency.class.getName() ).sqlTypes( mappings )[0]
+	    //};
+	}
+
+    public Class getReturnedClass() {
+        return Money.class;
+    }
+
+    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws SQLException {
+        assert names.length == 2;
+        BigDecimal amount = BigDecimalType.INSTANCE.get( names[0] ); // already handles null check
+        Currency currency = CurrencyType.INSTANCE.get( names[1] ); // already handles null check
+        return amount == null && currency == null
+                ? null
+                : new Money( amount, currency );
+    }
+
+    public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session)
+            throws SQLException {
+        if ( value == null ) {
+            BigDecimalType.INSTANCE.set( st, null, index );
+            CurrencyType.INSTANCE.set( st, null, index+1 );
+        }
+        else {
+            final Money money = (Money) value;
+            BigDecimalType.INSTANCE.set( st, money.getAmount(), index );
+            CurrencyType.INSTANCE.set( st, money.getCurrency(), index+1 );
+        }
+    }
+
+    ...
+}]]></programlisting>
+                    <programlisting role="JAVA">
+                        Configuration cfg = new Configuration();
+                        cfg.registerTypeOverride( new MoneyType() );
+                        cfg...;
+                    </programlisting>
+                </example>
+                <important>
+                    <para>
+                        It is important that we registered the type <emphasis>before</emphasis> adding mappings.
+                    </para>
+                </important>
+            </para>
+        </section>
+
+        <section id="types.custom.ut">
+            <title>Custom types using <interfacename>org.hibernate.usertype.UserType</interfacename></title>
+            <note>
+                <para>
+                    Both <interfacename>org.hibernate.usertype.UserType</interfacename> and
+                    <interfacename>org.hibernate.usertype.CompositeUserType</interfacename> were originally
+                    added to isolate user code from internal changes to the <interfacename>org.hibernate.type.Type</interfacename>
+                    interfaces.
+                </para>
+            </note>
+            <para>
+                The second approach is the use the <interfacename>org.hibernate.usertype.UserType</interfacename>
+                interface, which presents a somewhat simplified view of the <interfacename>org.hibernate.type.Type</interfacename>
+                interface.  Using a <interfacename>org.hibernate.usertype.UserType</interfacename>, our
+                <classname>Money</classname> custom type would look as follows:
+            </para>
+            <example id="types.custom.ut.ex.definition">
+                <title>Defining the custom UserType</title>
+                <programlisting role="JAVA"><![CDATA[public class MoneyType implements UserType {
+    public int[] sqlTypes() {
+        return new int[] {
+                BigDecimalType.INSTANCE.sqlType(),
+                CurrencyType.INSTANCE.sqlType(),
+        };
+    }
+
+    public Class getReturnedClass() {
+        return Money.class;
+    }
+
+    public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws SQLException {
+        assert names.length == 2;
+        BigDecimal amount = BigDecimalType.INSTANCE.get( names[0] ); // already handles null check
+        Currency currency = CurrencyType.INSTANCE.get( names[1] ); // already handles null check
+        return amount == null && currency == null
+                ? null
+                : new Money( amount, currency );
+    }
+
+    public void nullSafeSet(PreparedStatement st, Object value, int index) throws SQLException {
+        if ( value == null ) {
+            BigDecimalType.INSTANCE.set( st, null, index );
+            CurrencyType.INSTANCE.set( st, null, index+1 );
+        }
+        else {
+            final Money money = (Money) value;
+            BigDecimalType.INSTANCE.set( st, money.getAmount(), index );
+            CurrencyType.INSTANCE.set( st, money.getCurrency(), index+1 );
+        }
+    }
+
+    ...
+}]]></programlisting>
+            </example>
+            <para>
+                There is not much difference between the <interfacename>org.hibernate.type.Type</interfacename> example
+                and the <interfacename>org.hibernate.usertype.UserType</interfacename> example, but that is only because
+                of the snippets shown.  If you choose the <interfacename>org.hibernate.type.Type</interfacename> approach
+                there are quite a few more methods you would need to implement as compared to the
+                <interfacename>org.hibernate.usertype.UserType</interfacename>.
+            </para>
+        </section>
+
+        <section id="types.custom.cut">
+            <title>Custom types using <interfacename>org.hibernate.usertype.CompositeUserType</interfacename></title>
+            <para>
+                The third and final approach is the use the <interfacename>org.hibernate.usertype.CompositeUserType</interfacename>
+                interface, which differs from <interfacename>org.hibernate.usertype.UserType</interfacename> in that it
+                gives us the ability to provide Hibernate the information to handle the composition within the
+                <classname>Money</classname> class (specifically the 2 attributes).  THis would give us the capability,
+                for example, to reference the <literal>amount</literal> attribute in an HQL query.  Using a
+                <interfacename>org.hibernate.usertype.UserType</interfacename>, our <classname>Money</classname> custom
+                type would look as follows:
+            </para>
+
+            <example id="types.custom.cut.ex.definition">
+                <title>Defining the custom CompositeUserType</title>
+                <programlisting role="JAVA"><![CDATA[public class MoneyType implements CompositeUserType {
+    public String[] getPropertyNames() {
+        // ORDER IS IMPORTANT!  it must match the order the columns are defined in the property mapping
+        return new String[] { "amount", "currency" };
+    }
+
+    public Type[] getPropertyTypes() {
+        return new Type[] { BigDecimalType.INSTANCE, CurrencyType.INSTANCE };
+    }
+
+    public Class getReturnedClass() {
+        return Money.class;
+    }
+
+    public Object getPropertyValue(Object component, int propertyIndex) {
+        if ( component == null ) {
+            return null;
+        }
+
+        final Money money = (Money) component;
+        switch ( propertyIndex ) {
+            case 0: {
+                return money.getAmount();
+            }
+            case 1: {
+                return money.getCurrency();
+            }
+            default: {
+                throw new HibernateException( "Invalid property index [" + propertyIndex + "]" );
+            }
+        }
+    }
+
+	public void setPropertyValue(Object component, int propertyIndex, Object value) throws HibernateException {
+        if ( component == null ) {
+            return;
+        }
+
+        final Money money = (Money) component;
+        switch ( propertyIndex ) {
+            case 0: {
+                money.setAmount( (BigDecimal) value );
+                break;
+            }
+            case 1: {
+                money.setCurrency( (Currency) value );
+                break;
+            }
+            default: {
+                throw new HibernateException( "Invalid property index [" + propertyIndex + "]" );
+            }
+        }
+	}
+
+    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws SQLException {
+        assert names.length == 2;
+        BigDecimal amount = BigDecimalType.INSTANCE.get( names[0] ); // already handles null check
+        Currency currency = CurrencyType.INSTANCE.get( names[1] ); // already handles null check
+        return amount == null && currency == null
+                ? null
+                : new Money( amount, currency );
+    }
+
+    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws SQLException {
+        if ( value == null ) {
+            BigDecimalType.INSTANCE.set( st, null, index );
+            CurrencyType.INSTANCE.set( st, null, index+1 );
+        }
+        else {
+            final Money money = (Money) value;
+            BigDecimalType.INSTANCE.set( st, money.getAmount(), index );
+            CurrencyType.INSTANCE.set( st, money.getCurrency(), index+1 );
+        }
+    }
+
+    ...
+}]]></programlisting>
+            </example>
+        </section>
+
+    </section>
+
+    <section id="types.registry">
+        <title>Type registry</title>
+        <para>
+            Internally Hibernate uses a registry of basic types (see <xref linkend="types.value.basic"/>) when
+            it needs to resolve the specific <interfacename>org.hibernate.type.Type</interfacename> to use in certain
+            situations.  It also provides a way for applications to add extra basic type registrations as well as
+            override the standard basic type registrations.
+        </para>
+        <para>
+            To register a new type or to override an existing type registration, applications would make use of the
+            <methodname>registerTypeOverride</methodname> method of the <classname>org.hibernate.cfg.Configuration</classname>
+            class when bootstrapping Hibernate.  For example, lets say you want Hibernate to use your custom
+            <classname>SuperDuperStringType</classname>; during bootstrap you would call:
+            <example id="type.registry.override.ex">
+                <title>Overriding the standard <classname>StringType</classname></title>
+                <programlisting role="JAVA"><![CDATA[Configuration cfg = ...;
+    cfg.registerTypeOverride( new SuperDuperStringType() );]]></programlisting>
+            </example>
+        </para>
+        <para>
+            The argument to <methodname>registerTypeOverride</methodname> is a <interfacename>org.hibernate.type.BasicType</interfacename>
+            which is a specialization of the <interfacename>org.hibernate.type.Type</interfacename> we saw before.  It
+            adds a single method:
+            <example>
+                <title>Snippet from BasicType.java</title>
+                <programlisting role="JAVA" >
+    /**
+	 * Get the names under which this type should be registered in the type registry.
+	 *
+	 * @return The keys under which to register this type.
+	 */
+	public String[] getRegistrationKeys();
+                </programlisting>
+            </example>
+            One approach is to use inheritance (<classname>SuperDuperStringType</classname> extends 
+            <classname>org.hibernate.typeStringType</classname>).  Another approach is to use delegation.
+        </para>
+        <important>
+            <para>
+                Currently UserType and CompositeUserType cannot be registered with the registry.  See
+                <ulink url="http://opensource.atlassian.com/projects/hibernate/browse/HHH-5262"/> for details.
+            </para>
+        </important>
+    </section>
+
+</chapter>



More information about the hibernate-commits mailing list