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

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Jun 14 08:34:33 EDT 2010


Author: hardy.ferentschik
Date: 2010-06-14 08:34:32 -0400 (Mon, 14 Jun 2010)
New Revision: 19725

Modified:
   core/trunk/documentation/manual/src/main/docbook/en-US/content/collection_mapping.xml
Log:
HHH-5149 Updated collection mapping to take annotatons into consideration

Modified: core/trunk/documentation/manual/src/main/docbook/en-US/content/collection_mapping.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/collection_mapping.xml	2010-06-14 05:28:18 UTC (rev 19724)
+++ core/trunk/documentation/manual/src/main/docbook/en-US/content/collection_mapping.xml	2010-06-14 12:34:32 UTC (rev 19725)
@@ -1,4 +1,4 @@
-<?xml version='1.0' encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <!--
   ~ Hibernate, Relational Persistence for Idiomatic Java
   ~
@@ -22,140 +22,276 @@
   ~ 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" [
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
+"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
 <!ENTITY % BOOK_ENTITIES SYSTEM "../HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.ent">
 %BOOK_ENTITIES;
-
 ]>
-
 <chapter id="collections">
-    <title>Collection mapping</title>
+  <title>Collection mapping</title>
 
-    <section id="collections-persistent" revision="3">
-        <title>Persistent collections</title>
-        
-        <para>
-            Hibernate requires that persistent collection-valued fields be declared
-            as an interface type. For example:
-        </para>
-        
-        <programlisting role="JAVA"><![CDATA[public class Product {
+  <section id="collections-persistent" revision="3">
+    <title>Persistent collections</title>
+
+    <para>Of course Hibernate also allows to persist collections. These
+    persistent collections can contain almost any other Hibernate type,
+    including: basic types, custom types, components and references to other
+    entities. This is an important distinction. An object in a collection
+    might be handled with "value" semantics (its life cycle fully depends on
+    the collection owner), or it might be a reference to another entity with
+    its own life cycle. In the latter case, only the "link" between the two
+    objects is considered to be a state held by the collection.</para>
+
+    <para>As a requirement persistent collection-valued fields must be
+    declared as an interface type. For example:</para>
+
+    <example id="example-collection-values-field">
+      <title>Persistent collection-valued fields must be interfaces</title>
+
+      <programlisting role="JAVA">public class Product {
     private String serialNumber;
     private Set parts = new HashSet();
     
     public Set getParts() { return parts; }
     void setParts(Set parts) { this.parts = parts; }
+
     public String getSerialNumber() { return serialNumber; }
     void setSerialNumber(String sn) { serialNumber = sn; }
-}]]></programlisting>
-        
-        <para>
-            The actual interface might be <literal>java.util.Set</literal>,
-            <literal>java.util.Collection</literal>, <literal>java.util.List</literal>,
-            <literal>java.util.Map</literal>, <literal>java.util.SortedSet</literal>,
-            <literal>java.util.SortedMap</literal> or anything you like  
-            ("anything you like" means you will have to write an implementation of 
-            <literal>org.hibernate.usertype.UserCollectionType</literal>.)
-        </para>
-        
-        <para>
-            Notice how the instance variable was initialized with an instance of
-            <literal>HashSet</literal>. This is the best way to initialize collection
-            valued properties of newly instantiated (non-persistent) instances. When
-            you make the instance persistent, by calling <literal>persist()</literal>
-            for example, Hibernate will actually replace the <literal>HashSet</literal>
-            with an instance of Hibernate's own implementation of <literal>Set</literal>.
-            Be aware of the following errors:
-        </para>
-        
-        <programlisting role="JAVA"><![CDATA[Cat cat = new DomesticCat();
+}</programlisting>
+    </example>
+
+    <para>The actual interface might be <literal>java.util.Set</literal>,
+    <literal>java.util.Collection</literal>,
+    <literal>java.util.List</literal>, <literal>java.util.Map</literal>,
+    <literal>java.util.SortedSet</literal>,
+    <literal>java.util.SortedMap</literal> or anything you like ("anything you
+    like" means you will have to write an implementation of
+    <literal>org.hibernate.usertype.UserCollectionType</literal>).</para>
+
+    <para>Notice how in <xref linkend="example-collection-values-field" /> the
+    instance variable <literal>parts</literal> was initialized with an
+    instance of <literal>HashSet</literal>. This is the best way to initialize
+    collection valued properties of newly instantiated (non-persistent)
+    instances. When you make the instance persistent, by calling
+    <literal>persist()</literal>, Hibernate will actually replace the
+    <literal>HashSet</literal> with an instance of Hibernate's own
+    implementation of <literal>Set</literal>. Be aware of the following
+    error:</para>
+
+    <example>
+      <title>Hibernate uses its own collection implementations</title>
+
+      <programlisting role="JAVA">Cat cat = new DomesticCat();
 Cat kitten = new DomesticCat();
 ....
 Set kittens = new HashSet();
 kittens.add(kitten);
 cat.setKittens(kittens);
 session.persist(cat);
+
 kittens = cat.getKittens(); // Okay, kittens collection is a Set
-(HashSet) cat.getKittens(); // Error!]]></programlisting>
+(HashSet) cat.getKittens(); // Error!</programlisting>
+    </example>
 
-        <para>
-            The persistent collections injected by Hibernate behave like
-            <literal>HashMap</literal>, <literal>HashSet</literal>,
-            <literal>TreeMap</literal>, <literal>TreeSet</literal> or
-            <literal>ArrayList</literal>, depending on the interface type.
-        </para>
+    <para>The persistent collections injected by Hibernate behave like
+    <literal>HashMap</literal>, <literal>HashSet</literal>,
+    <literal>TreeMap</literal>, <literal>TreeSet</literal> or
+    <literal>ArrayList</literal>, depending on the interface type.</para>
 
-        <para>
-            Collections instances have the usual behavior of value types. They are 
-            automatically persisted when referenced by a persistent object and 
-            are automatically deleted when unreferenced. If a collection is passed from one
-            persistent object to another, its elements might be moved from one table to
-            another. Two entities cannot share a reference to the same collection 
-            instance. Due to the underlying relational model, collection-valued properties
-            do not support null value semantics. Hibernate does not distinguish between 
-            a null collection reference and an empty collection.
-        </para>
+    <para>Collections instances have the usual behavior of value types. They
+    are automatically persisted when referenced by a persistent object and are
+    automatically deleted when unreferenced. If a collection is passed from
+    one persistent object to another, its elements might be moved from one
+    table to another. Two entities cannot share a reference to the same
+    collection instance. Due to the underlying relational model,
+    collection-valued properties do not support null value semantics.
+    Hibernate does not distinguish between a null collection reference and an
+    empty collection.</para>
 
-        <para>
-            Use persistent collections 
-            the same way you use ordinary Java collections. However, please ensure you understand 
-            the semantics of bidirectional associations (these are discussed later).
-        </para>
+    <para>Use persistent collections the same way you use ordinary Java
+    collections. However, please ensure you understand the semantics of
+    bidirectional associations (see <xref
+    linkend="collections-bidirectional" />).</para>
+  </section>
 
-    </section>
+  <section id="collections-mapping" revision="4">
+    <title>Collection mappings</title>
 
-    <section id="collections-mapping" revision="4">
-        <title>Collection mappings</title>
+    <para>Using annotations you can map <classname>Collection</classname>s,
+    <classname>Lists</classname>, <classname>Maps</classname> and
+    <classname>Sets</classname> of associated entities using @OneToMany and
+    @ManyToMany. For collections of a basic or embeddable type use
+    @ElementCollection. In the simplest case a collection mapping looks like
+    this:</para>
 
-        <tip>
-            <para>
-                There are quite a range of mappings that can be generated for collections that cover
-                many common relational models. We suggest you experiment with the schema generation tool
-                so that you understand how various mapping declarations translate to database tables.
-            </para>
-        </tip>
+    <example>
+      <title>Collection mapping using annotations</title>
 
-        <para>
-            The Hibernate mapping element used for mapping a collection depends upon
-            the type of interface. For example, a <literal>&lt;set&gt;</literal> 
-            element is used for mapping properties of type <literal>Set</literal>.
-        </para>
-        
-        <programlisting role="JAVA"><![CDATA[<class name="Product">
-    <id name="serialNumber" column="productSerialNumber"/>
-    <set name="parts">
-        <key column="productSerialNumber" not-null="true"/>
-        <one-to-many class="Part"/>
-    </set>
-</class>]]></programlisting>
+      <programlisting role="JAVA">@Entity
+public class Product {
 
-        <para>
-            Apart from <literal>&lt;set&gt;</literal>, there is also 
-            <literal>&lt;list&gt;</literal>, <literal>&lt;map&gt;</literal>,
-            <literal>&lt;bag&gt;</literal>, <literal>&lt;array&gt;</literal> and
-            <literal>&lt;primitive-array&gt;</literal> mapping elements. The
-            <literal>&lt;map&gt;</literal> element is representative:
-        </para>
+    private String serialNumber;
+    private Set&lt;Part&gt; parts = new HashSet&lt;Part&gt;();
 
-        <programlistingco role="XML">
-            <areaspec>
-                <area id="mappingcollection1" coords="2"/>
-                <area id="mappingcollection2" coords="3"/>
-                <area id="mappingcollection3" coords="4"/>
-                <area id="mappingcollection4" coords="5"/>
-                <area id="mappingcollection5" coords="6"/>
-                <area id="mappingcollection6" coords="7"/>
-                <area id="mappingcollection7" coords="8"/>
-                <area id="mappingcollection8" coords="9"/>
-                <area id="mappingcollection9" coords="10"/>
-                <area id="mappingcollection10" coords="11"/>
-                <area id="mappingcollection11" coords="12"/>
-                <area id="mappingcollection12" coords="13"/>
-                <area id="mappingcollection13" coords="14"/>
-                <area id="mappingcollection14" coords="15"/>
-            </areaspec>
-            <programlisting><![CDATA[<map
+    @Id
+    public String getSerialNumber() { return serialNumber; }
+    void setSerialNumber(String sn) { serialNumber = sn; }
+   
+    @OneToMany
+    public Set&lt;Part&gt; getParts() { return parts; }
+    void setParts(Set parts) { this.parts = parts; }
+}
+
+
+ at Entity
+public class Part {
+   ...
+}</programlisting>
+    </example>
+
+    <para>The <literal>@OneToMany</literal> and <literal>@ManyToOne</literal>
+    annotations have several options and there are other annotations which can
+    be used in in combination with these annotations. But lets first see how
+    collections are mapped using Hibernate mapping files. Here the situation
+    is more complex than in the annotation case, since the mapping element
+    used for mapping a collection depends upon the type of interface. For
+    example, a <literal>&lt;set&gt;</literal> element is used for mapping
+    properties of type <literal>Set</literal>.</para>
+
+    <example floatstyle="" id="example.collections.set">
+      <title>Mapping a Set using &lt;set&gt;</title>
+
+      <programlisting role="JAVA">&lt;class name="Product"&gt;
+    &lt;id name="serialNumber" column="productSerialNumber"/&gt;
+    &lt;set name="parts"&gt;
+        &lt;key column="productSerialNumber" not-null="true"/&gt;
+        &lt;one-to-many class="Part"/&gt;
+    &lt;/set&gt;
+&lt;/class&gt;</programlisting>
+    </example>
+
+    <para>In <xref linkend="example.collections.set" /> a
+    <emphasis>one-to-many association</emphasis> links the
+    <literal>Product</literal> and <literal>Part</literal> entities. This
+    association requires the existence of a foreign key column and possibly an
+    index column to the <literal>Part</literal> table. This mapping loses
+    certain semantics of normal Java collections:</para>
+
+    <itemizedlist spacing="compact">
+      <listitem>
+        <para>An instance of the contained entity class cannot belong to more
+        than one instance of the collection.</para>
+      </listitem>
+
+      <listitem>
+        <para>An instance of the contained entity class cannot appear at more
+        than one value of the collection index.</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>The <literal>&lt;one-to-many&gt;</literal> tag has the following
+    options.</para>
+
+    <example>
+      <title>options of &lt;one-to-many&gt; tag</title>
+
+      <programlistingco role="XML">
+        <areaspec>
+          <area coords="2" id="onetomany1" />
+
+          <area coords="3" id="onetomany2" />
+
+          <area coords="4" id="onetomany3" />
+        </areaspec>
+
+        <programlisting>&lt;one-to-many
+        class="ClassName"
+        not-found="ignore|exception"
+        entity-name="EntityName"
+        node="element-name"
+        embed-xml="true|false"
+    /&gt;</programlisting>
+
+        <calloutlist>
+          <callout arearefs="onetomany1">
+            <para><literal>class</literal> (required): the name of the
+            associated class.</para>
+          </callout>
+
+          <callout arearefs="onetomany2">
+            <para><literal>not-found</literal> (optional - defaults to
+            <literal>exception</literal>): specifies how cached identifiers
+            that reference missing rows will be handled.
+            <literal>ignore</literal> will treat a missing row as a null
+            association.</para>
+          </callout>
+
+          <callout arearefs="onetomany3">
+            <para><literal>entity-name</literal> (optional): the entity name
+            of the associated class, as an alternative to
+            <literal>class</literal>.</para>
+          </callout>
+        </calloutlist>
+      </programlistingco>
+    </example>
+
+    <para>The <literal>&lt;one-to-many&gt;</literal> element does not need to
+    declare any columns. Nor is it necessary to specify the
+    <literal>table</literal> name anywhere.</para>
+
+    <warning>
+      <para>If the foreign key column of a
+      <literal>&lt;one-to-many&gt;</literal> association is declared
+      <literal>NOT NULL</literal>, you must declare the
+      <literal>&lt;key&gt;</literal> mapping
+      <literal>not-null="true"</literal> or <emphasis>use a bidirectional
+      association</emphasis> with the collection mapping marked
+      <literal>inverse="true"</literal>. See the discussion of bidirectional
+      associations later in this chapter for more information.</para>
+    </warning>
+
+    <para>Apart from the <literal>&lt;set&gt; </literal>tag as shown in <xref
+    linkend="example.collections.set" />, there is also
+    <literal>&lt;list&gt;</literal>, <literal>&lt;map&gt;</literal>,
+    <literal>&lt;bag&gt;</literal>, <literal>&lt;array&gt;</literal> and
+    <literal>&lt;primitive-array&gt;</literal> mapping elements. The
+    <literal>&lt;map&gt;</literal> element is representative:</para>
+
+    <example>
+      <title>Elements of the &lt;map&gt; mapping</title>
+
+      <programlistingco role="XML">
+        <areaspec>
+          <area coords="2" id="mappingcollection1" />
+
+          <area coords="3" id="mappingcollection2" />
+
+          <area coords="4" id="mappingcollection3" />
+
+          <area coords="5" id="mappingcollection4" />
+
+          <area coords="6" id="mappingcollection5" />
+
+          <area coords="7" id="mappingcollection6" />
+
+          <area coords="8" id="mappingcollection7" />
+
+          <area coords="9" id="mappingcollection8" />
+
+          <area coords="10" id="mappingcollection9" />
+
+          <area coords="11" id="mappingcollection10" />
+
+          <area coords="12" id="mappingcollection11" />
+
+          <area coords="13" id="mappingcollection12" />
+
+          <area coords="14" id="mappingcollection13" />
+
+          <area coords="15" id="mappingcollection14" />
+        </areaspec>
+
+        <programlisting>&lt;map
     name="propertyName"
     table="table_name"
     schema="schema_name"
@@ -172,300 +308,660 @@
     mutable="true|false"
     node="element-name|."
     embed-xml="true|false"
->
+&gt;
 
-    <key .... />
-    <map-key .... />
-    <element .... />
-</map>]]></programlisting>
-            <calloutlist>
-                <callout arearefs="mappingcollection1">
-                    <para>
-                        <literal>name</literal>: the collection property name
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection2">
-                    <para>
-                        <literal>table</literal> (optional - defaults to property name): the
-                        name of the collection table. It is not used for one-to-many associations.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection3">
-                    <para>
-                        <literal>schema</literal> (optional): the name of a table schema to
-                        override the schema declared on the root element
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection4">
-                    <para>
-                        <literal>lazy</literal> (optional - defaults to <literal>true</literal>):
-                        disables lazy fetching and specifies that the association is 
-                        always eagerly fetched. It can also be used to enable "extra-lazy" fetching where most 
-                        operations do not initialize the collection. This is suitable for large 
-                        collections.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection5">
-                    <para>
-                        <literal>inverse</literal> (optional - defaults to <literal>false</literal>):
-                        marks this collection as the "inverse" end of a bidirectional association.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection6">
-                    <para>
-                        <literal>cascade</literal> (optional - defaults to <literal>none</literal>):
-                        enables operations to cascade to child entities.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection7">
-                    <para>
-                        <literal>sort</literal> (optional): specifies a sorted collection with
-                        <literal>natural</literal> sort order or a given comparator class.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection8">
-                    <para>
-                        <literal>order-by</literal> (optional, JDK1.4 only): specifies a table column or columns
-                        that define the iteration order of the <literal>Map</literal>, <literal>Set</literal>
-                        or bag, together with an optional <literal>asc</literal> or <literal>desc</literal>.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection9">
-                    <para>
-                        <literal>where</literal> (optional): specifies an arbitrary SQL <literal>WHERE</literal>
-                        condition that is used when retrieving or removing the collection. This is useful if the
-                        collection needs to contain only a subset of the available data.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection10">
-                    <para>
-                        <literal>fetch</literal> (optional, defaults to <literal>select</literal>): chooses
-                        between outer-join fetching, fetching by sequential select, and fetching by sequential
-                        subselect.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection11">
-                    <para>
-                        <literal>batch-size</literal> (optional, defaults to <literal>1</literal>): specifies a
-                        "batch size" for lazily fetching instances of this collection.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection12">
-                    <para>
-                        <literal>access</literal> (optional - defaults to <literal>property</literal>): the
-                        strategy Hibernate uses for accessing the collection property value.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection13">
-                    <para>
-                        <literal>optimistic-lock</literal> (optional - defaults to <literal>true</literal>): 
-                        specifies that changes to the state of the collection results in increments of the
-                        owning entity's version. For one-to-many associations you may want to
-                        disable this setting.
-                    </para>
-                </callout>
-                <callout arearefs="mappingcollection14">
-                    <para>
-                        <literal>mutable</literal> (optional - defaults to <literal>true</literal>): 
-                        a value of <literal>false</literal> specifies that the elements of the 
-                        collection never change. This allows for minor performance optimization in some cases.
-                    </para>
-                </callout>
-            </calloutlist>
-        </programlistingco>
+    &lt;key .... /&gt;
+    &lt;map-key .... /&gt;
+    &lt;element .... /&gt;
+&lt;/map&gt;</programlisting>
 
-        <section id="collections-foreignkeys" >
-           <title>Collection foreign keys</title>
-    
-            <para>
-                Collection instances are distinguished in the database by the foreign key of
-                the entity that owns the collection. This foreign key is referred to as the
-                <emphasis>collection key column</emphasis>, or columns, of the collection 
-                table. The collection key column is mapped by the <literal>&lt;key&gt;</literal> 
-                element. 
-            </para>
-    
-            <para>
-                There can be a nullability constraint on the foreign key column. For most
-                collections, this is implied. For unidirectional one-to-many associations,
-                the foreign key column is nullable by default, so you may need to specify
-                <literal>not-null="true"</literal>.
-            </para>
-    
-            <programlisting role="XML"><![CDATA[<key column="productSerialNumber" not-null="true"/>]]></programlisting>
-    
-            <para>
-                The foreign key constraint can use <literal>ON DELETE CASCADE</literal>.
-            </para>
-    
-            <programlisting role="XML"><![CDATA[<key column="productSerialNumber" on-delete="cascade"/>]]></programlisting>
-            
-            <para>
-                See the previous chapter for a full definition of the <literal>&lt;key&gt;</literal> 
-                element.
-            </para>
-            
-        </section>
-        
-        <section id="collections-elements" >
-            <title>Collection elements</title>
-    
-            <para>
-                Collections can contain almost any other Hibernate type, including: basic types,
-                custom types, components and references to other entities. This is an
-                important distinction. An object in a collection might be handled with "value" 
-                semantics (its life cycle fully depends on the collection owner), or it might be a
-                reference to another entity with its own life cycle. In the latter case, only the 
-                "link" between the two objects is considered to be a state held by the collection. 
-            </para>
-                
-            <para>
-                The contained type is referred to as the <emphasis>collection element type</emphasis>. 
-                Collection elements are mapped by <literal>&lt;element&gt;</literal> or
-                <literal>&lt;composite-element&gt;</literal>, or in the case of entity references, 
-                with <literal>&lt;one-to-many&gt;</literal> or <literal>&lt;many-to-many&gt;</literal>. 
-                The first two map elements with value semantics, the next two are used to map entity 
-                associations.
-            </para>
-            
-        </section>
-        
-        <section id="collections-indexed">
-            <title>Indexed collections</title>
-    
-            <para>
-                All collection mappings, except those with set and bag semantics, need an
-                <emphasis>index column</emphasis> in the collection table. An index column is a column that maps to an
-                array index, or <literal>List</literal> index, or <literal>Map</literal> key. The
-                index of a <literal>Map</literal> may be of any basic type, mapped with 
-                <literal>&lt;map-key&gt;</literal>. It can be an entity reference mapped with 
-                <literal>&lt;map-key-many-to-many&gt;</literal>, or it can be a composite type
-                mapped with <literal>&lt;composite-map-key&gt;</literal>. The index of an array or 
-                list is always of type <literal>integer</literal> and is mapped using the 
-                <literal>&lt;list-index&gt;</literal> element. The mapped column contains 
-                sequential integers that are numbered from zero by default.
-            </para>
+        <calloutlist>
+          <callout arearefs="mappingcollection1">
+            <para><literal>name</literal>: the collection property name</para>
+          </callout>
 
-        <programlistingco role="XML">
+          <callout arearefs="mappingcollection2">
+            <para><literal>table</literal> (optional - defaults to property
+            name): the name of the collection table. It is not used for
+            one-to-many associations.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection3">
+            <para><literal>schema</literal> (optional): the name of a table
+            schema to override the schema declared on the root element</para>
+          </callout>
+
+          <callout arearefs="mappingcollection4">
+            <para><literal>lazy</literal> (optional - defaults to
+            <literal>true</literal>): disables lazy fetching and specifies
+            that the association is always eagerly fetched. It can also be
+            used to enable "extra-lazy" fetching where most operations do not
+            initialize the collection. This is suitable for large
+            collections.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection5">
+            <para><literal>inverse</literal> (optional - defaults to
+            <literal>false</literal>): marks this collection as the "inverse"
+            end of a bidirectional association.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection6">
+            <para><literal>cascade</literal> (optional - defaults to
+            <literal>none</literal>): enables operations to cascade to child
+            entities.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection7">
+            <para><literal>sort</literal> (optional): specifies a sorted
+            collection with <literal>natural</literal> sort order or a given
+            comparator class.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection8">
+            <para><literal>order-by</literal> (optional): specifies a table
+            column or columns that define the iteration order of the
+            <literal>Map</literal>, <literal>Set</literal> or bag, together
+            with an optional <literal>asc</literal> or
+            <literal>desc</literal>.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection9">
+            <para><literal>where</literal> (optional): specifies an arbitrary
+            SQL <literal>WHERE</literal> condition that is used when
+            retrieving or removing the collection. This is useful if the
+            collection needs to contain only a subset of the available
+            data.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection10">
+            <para><literal>fetch</literal> (optional, defaults to
+            <literal>select</literal>): chooses between outer-join fetching,
+            fetching by sequential select, and fetching by sequential
+            subselect.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection11">
+            <para><literal>batch-size</literal> (optional, defaults to
+            <literal>1</literal>): specifies a "batch size" for lazily
+            fetching instances of this collection.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection12">
+            <para><literal>access</literal> (optional - defaults to
+            <literal>property</literal>): the strategy Hibernate uses for
+            accessing the collection property value.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection13">
+            <para><literal>optimistic-lock</literal> (optional - defaults to
+            <literal>true</literal>): specifies that changes to the state of
+            the collection results in increments of the owning entity's
+            version. For one-to-many associations you may want to disable this
+            setting.</para>
+          </callout>
+
+          <callout arearefs="mappingcollection14">
+            <para><literal>mutable</literal> (optional - defaults to
+            <literal>true</literal>): a value of <literal>false</literal>
+            specifies that the elements of the collection never change. This
+            allows for minor performance optimization in some cases.</para>
+          </callout>
+        </calloutlist>
+      </programlistingco>
+    </example>
+
+    <section id="collections-foreignkeys">
+      <title>Collection foreign keys</title>
+
+      <para>Collection instances are distinguished in the database by the
+      foreign key of the entity that owns the collection. This foreign key is
+      referred to as the <emphasis>collection key column</emphasis>, or
+      columns, of the collection table. The collection key column is mapped by
+      the <literal>@JoinColumn</literal> annotation respectively the
+      <literal>&lt;key&gt;</literal> XML element.</para>
+
+      <para>There can be a nullability constraint on the foreign key column.
+      For most collections, this is implied. For unidirectional one-to-many
+      associations, the foreign key column is nullable by default, so you may
+      need to specify</para>
+
+      <programlisting role="Java">@JoinColumn(nullable=false)</programlisting>
+
+      <para>or</para>
+
+      <programlisting role="XML">&lt;key column="productSerialNumber" not-null="true"/&gt;</programlisting>
+
+      <para>The foreign key constraint can use <literal>ON DELETE
+      CASCADE</literal>. In XML this can be expressed via:</para>
+
+      <programlisting role="XML">&lt;key column="productSerialNumber" on-delete="cascade"/&gt;</programlisting>
+
+      <para>In annotations the Hibernate specific annotation @OnDelete has to
+      be used.</para>
+
+      <programlisting role="Java">@OnDelete(action=OnDeleteAction.CASCADE)</programlisting>
+
+      <para>See <xref linkend="section-key" /> for more information about the
+      <literal>&lt;key&gt;</literal> element.</para>
+    </section>
+
+    <section id="collections-indexed">
+      <title id="section.indexed.collections">Indexed collections</title>
+
+      <section>
+        <title>Lists</title>
+
+        <para>Lists can be mapped in two different ways:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>as ordered lists, where the order is not materialized in the
+            database</para>
+          </listitem>
+
+          <listitem>
+            <para>as indexed lists, where the order is materialized in the
+            database</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>To order lists in memory, add
+        <literal>@javax.persistence.OrderBy</literal> to your property. This
+        annotation takes as parameter a list of comma separated properties (of
+        the target entity) and order the collection accordingly (eg
+        <code>firstname asc, age desc</code>), if the string is empty, the
+        collection will be ordered by the primary key of the target
+        entity.</para>
+
+        <example>
+          <title>Ordered lists using <classname>@OrderBy</classname></title>
+
+          <programlisting language="JAVA" role="JAVA">@Entity
+public class Customer {
+   @Id @GeneratedValue public Integer getId() { return id; }
+   public void setId(Integer id) { this.id = id; }
+   private Integer id;
+
+   @OneToMany(mappedBy="customer")
+   @OrderBy("number")
+   public List&lt;Order&gt; getOrders() { return orders; }
+   public void setOrders(List&lt;Order&gt; orders) { this.orders = orders; }
+   private List&lt;Order&gt; orders;
+}
+
+ at Entity
+public class Order {
+   @Id @GeneratedValue public Integer getId() { return id; }
+   public void setId(Integer id) { this.id = id; }
+   private Integer id;
+
+   public String getNumber() { return number; }
+   public void setNumber(String number) { this.number = number; }
+   private String number;
+
+   @ManyToOne
+   public Customer getCustomer() { return customer; }
+   public void setCustomer(Customer customer) { this.customer = customer; }
+   private Customer number;
+}
+
+-- Table schema
+|-------------| |----------|
+| Order       | | Customer |
+|-------------| |----------|
+| id          | | id       |
+| number      | |----------| 
+| customer_id |
+|-------------|</programlisting>
+        </example>
+
+        <para>To store the index value in a dedicated column, use the
+        <classname>@javax.persistence.OrderColumn</classname> annotation on
+        your property. This annotations describes the column name and
+        attributes of the column keeping the index value. This column is
+        hosted on the table containing the association foreign key. If the
+        column name is not specified, the default is the name of the
+        referencing property, followed by underscore, followed by
+        <literal>ORDER</literal> (in the following example, it would be
+        <literal>orders_ORDER</literal>).</para>
+
+        <example>
+          <title>Additional index column using
+          <classname>@OrderColumn</classname></title>
+
+          <programlisting language="JAVA" role="JAVA">@Entity
+public class Customer {
+   @Id @GeneratedValue public Integer getId() { return id; }
+   public void setId(Integer id) { this.id = id; }
+   private Integer id;
+
+   @OneToMany(mappedBy="customer")
+   @OrderColumn(name="orders_index")
+   public List&lt;Order&gt; getOrders() { return orders; }
+   public void setOrders(List&lt;Order&gt; orders) { this.orders = orders; }
+   private List&lt;Order&gt; orders;
+}
+
+ at Entity
+public class Order {
+   @Id @GeneratedValue public Integer getId() { return id; }
+   public void setId(Integer id) { this.id = id; }
+   private Integer id;
+
+   public String getNumber() { return number; }
+   public void setNumber(String number) { this.number = number; }
+   private String number;
+
+   @ManyToOne
+   public Customer getCustomer() { return customer; }
+   public void setCustomer(Customer customer) { this.customer = customer; }
+   private Customer number;
+}
+
+-- Table schema
+|--------------| |----------|
+| Order        | | Customer |
+|--------------| |----------|
+| id           | | id       |
+| number       | |----------| 
+| customer_id  |
+| orders_order |
+|--------------|</programlisting>
+        </example>
+
+        <note>
+          <para>We recommend you to convert <classname>the legacy
+          @org.hibernate.annotations.IndexColumn</classname> usages to
+          <classname>@OrderColumn</classname> unless you are making use of the
+          base property. The <literal>base</literal> property lets you define
+          the index value of the first element (aka as base index). The usual
+          value is <literal>0</literal> or <literal>1</literal>. The default
+          is 0 like in Java.</para>
+        </note>
+
+        <para>Using mapping files the index of an array or list is always of
+        type <literal>integer</literal> and is mapped using the
+        <literal>&lt;list-index&gt;</literal> element. The mapped column
+        contains sequential integers that are numbered from zero by
+        default.</para>
+
+        <example>
+          <title>index-list element for indexed collections in xml
+          mapping</title>
+
+          <programlistingco role="XML">
             <areaspec>
-                <area id="index1" coords="2"/>
-                <area id="index2" coords="3"/>
-             </areaspec>
-            <programlisting><![CDATA[<list-index
+              <area coords="2" id="index1" />
+
+              <area coords="3" id="index2" />
+            </areaspec>
+
+            <programlisting>&lt;list-index
         column="column_name"
-        base="0|1|..."/>]]></programlisting>
+        base="0|1|..."/&gt;</programlisting>
+
             <calloutlist>
-                <callout arearefs="index1">
-                    <para>
-                        <literal>column_name</literal> (required): the name of the column holding the
-                        collection index values.
-                    </para>
-                </callout>
-                <callout arearefs="index1">
-                    <para>
-                        <literal>base</literal> (optional - defaults to <literal>0</literal>): the value
-                        of the index column that corresponds to the first element of the list or array.
-                    </para>
-                </callout>
+              <callout arearefs="index1">
+                <para><literal>column_name</literal> (required): the name of
+                the column holding the collection index values.</para>
+              </callout>
+
+              <callout arearefs="index1">
+                <para><literal>base</literal> (optional - defaults to
+                <literal>0</literal>): the value of the index column that
+                corresponds to the first element of the list or array.</para>
+              </callout>
             </calloutlist>
-        </programlistingco>
+          </programlistingco>
+        </example>
 
-        <programlistingco role="XML">
+        <para>If your table does not have an index column, and you still wish
+        to use <literal>List</literal> as the property type, you can map the
+        property as a Hibernate <emphasis>&lt;bag&gt;</emphasis>. A bag does
+        not retain its order when it is retrieved from the database, but it
+        can be optionally sorted or ordered.</para>
+      </section>
+
+      <section>
+        <title>Maps</title>
+
+        <para>Maps can borrow their keys from one of the associated entity
+        properties or have dedicated columns to store an explicit key.</para>
+
+        <para>To use one of the target entity property as a key of the map,
+        use <literal>@MapKey(name="myProperty")</literal>
+        (<literal>myProperty</literal> is a property name in the target
+        entity). When using <literal>@MapKey</literal> (without property
+        name), the target entity primary key is used. The map key uses the
+        same column as the property pointed out: there is no additional column
+        defined to hold the map key, and it does make sense since the map key
+        actually represent a target property. Be aware that once loaded, the
+        key is no longer kept in sync with the property, in other words, if
+        you change the property value, the key will not change automatically
+        in your Java model.</para>
+
+        <example>
+          <title>Use of target entity property as map key via
+          <classname>@MapKey</classname></title>
+
+          <programlisting language="JAVA" role="JAVA">@Entity
+public class Customer {
+   @Id @GeneratedValue public Integer getId() { return id; }
+   public void setId(Integer id) { this.id = id; }
+   private Integer id;
+
+   @OneToMany(mappedBy="customer")
+   @MapKey(name="number")
+   public Map&lt;String,Order&gt; getOrders() { return orders; }
+   public void setOrders(Map&lt;String,Order&gt; order) { this.orders = orders; }
+   private Map&lt;String,Order&gt; orders;
+}
+
+ at Entity
+public class Order {
+   @Id @GeneratedValue public Integer getId() { return id; }
+   public void setId(Integer id) { this.id = id; }
+   private Integer id;
+
+   public String getNumber() { return number; }
+   public void setNumber(String number) { this.number = number; }
+   private String number;
+
+   @ManyToOne
+   public Customer getCustomer() { return customer; }
+   public void setCustomer(Customer customer) { this.customer = customer; }
+   private Customer number;
+}
+
+-- Table schema
+|-------------| |----------|
+| Order       | | Customer |
+|-------------| |----------|
+| id          | | id       |
+| number      | |----------| 
+| customer_id |
+|-------------|</programlisting>
+        </example>
+
+        <para>Otherwise, the map key is mapped to a dedicated column or
+        columns. In order to customize the mapping use one of the following
+        annotations:</para>
+
+        <itemizedlist>
+          <listitem>
+            <para>@<classname>MapKeyColumn</classname> if the map key is a
+            basic type, if you don't specify the column name, the name of the
+            property followed by underscore followed by <literal>KEY</literal>
+            is used (for example <literal>orders_KEY</literal>).</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>@MapKeyEnumerated</classname> /
+            <classname>@MapKeyTemporal</classname> if the map key type is
+            respectively an enum or a <classname>Date</classname>.</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>@MapKeyJoinColumn</classname>/<classname>@MapKeyJoinColumns</classname>
+            if the map key type is another entity.</para>
+          </listitem>
+
+          <listitem>
+            <para><classname>@AttributeOverride</classname>/<classname>@AttributeOverrides</classname>
+            when the map key is a embeddable object. Use
+            <literal>key.</literal> as a prefix for your embeddable object
+            property names.</para>
+          </listitem>
+        </itemizedlist>
+
+        <para>You can also use <classname>@MapKeyClass</classname> to define
+        the type of the key if you don't use generics.</para>
+
+        <example>
+          <title>Map key as basic type using
+          <classname>@MapKeyColumn</classname></title>
+
+          <programlisting language="JAVA" role="JAVA">@Entity
+public class Customer {
+   @Id @GeneratedValue public Integer getId() { return id; }
+   public void setId(Integer id) { this.id = id; }
+   private Integer id;
+
+   @OneToMany @JoinTable(name="Cust_Order")
+   @MapKeyColumn(name="orders_number")
+   public Map&lt;String,Order&gt; getOrders() { return orders; }
+   public void setOrders(Map&lt;String,Order&gt; orders) { this.orders = orders; }
+   private Map&lt;String,Order&gt; orders;
+}
+
+ at Entity
+public class Order {
+   @Id @GeneratedValue public Integer getId() { return id; }
+   public void setId(Integer id) { this.id = id; }
+   private Integer id;
+
+   public String getNumber() { return number; }
+   public void setNumber(String number) { this.number = number; }
+   private String number;
+
+   @ManyToOne
+   public Customer getCustomer() { return customer; }
+   public void setCustomer(Customer customer) { this.customer = customer; }
+   private Customer number;
+}
+
+-- Table schema
+|-------------| |----------| |---------------|
+| Order       | | Customer | | Cust_Order    |
+|-------------| |----------| |---------------|
+| id          | | id       | | customer_id   |
+| number      | |----------| | order_id      |
+| customer_id |              | orders_number |
+|-------------|              |---------------|</programlisting>
+        </example>
+
+        <note>
+          <para>We recommend you to migrate from
+          <classname>@org.hibernate.annotations.MapKey</classname> /
+          <classname>@org.hibernate.annotation.MapKeyManyToMany</classname> to
+          the new standard approach described above</para>
+        </note>
+
+        <para>Using Hibernate mapping files there exists similar concepts
+        using <literal>&lt;map-key&gt;</literal>,
+        <literal>&lt;map-key-many-to-many&gt;</literal> and
+        <literal>&lt;composite-map-key&gt;</literal> which are even a little
+        more flexible since SQL expressions can be used to define the map key.
+        <literal>&lt;map-key&gt;</literal> is used for any basic type,
+        <literal>&lt;map-key-many-to-many&gt;</literal> for an entity
+        reference and <literal>&lt;composite-map-key&gt;</literal> for a
+        composite type.</para>
+
+        <example>
+          <title>map-key xml mapping element</title>
+
+          <programlistingco role="XML">
             <areaspec>
-                <area id="mapkey1" coords="2"/>
-                <area id="mapkey2" coords="3"/>
-                <area id="mapkey3" coords="4"/>
-             </areaspec>
-            <programlisting><![CDATA[<map-key
+              <area coords="2" id="mapkey1" />
+
+              <area coords="3" id="mapkey2" />
+
+              <area coords="4" id="mapkey3" />
+            </areaspec>
+
+            <programlisting>&lt;map-key
         column="column_name"
         formula="any SQL expression"
         type="type_name"
         node="@attribute-name"
-        length="N"/>]]></programlisting>
+        length="N"/&gt;</programlisting>
+
             <calloutlist>
-                <callout arearefs="mapkey1">
-                    <para>
-                        <literal>column</literal> (optional): the name of the column holding the
-                        collection index values.
-                    </para>
-                </callout>
-                <callout arearefs="mapkey2">
-                    <para>
-                        <literal>formula</literal> (optional): a SQL formula used to evaluate the
-                        key of the map.
-                    </para>
-                </callout>
-                <callout arearefs="mapkey3">
-                    <para>
-                        <literal>type</literal> (required): the type of the map keys.
-                    </para>
-                </callout>
+              <callout arearefs="mapkey1">
+                <para><literal>column</literal> (optional): the name of the
+                column holding the collection index values.</para>
+              </callout>
+
+              <callout arearefs="mapkey2">
+                <para><literal>formula</literal> (optional): a SQL formula
+                used to evaluate the key of the map.</para>
+              </callout>
+
+              <callout arearefs="mapkey3">
+                <para><literal>type</literal> (required): the type of the map
+                keys.</para>
+              </callout>
             </calloutlist>
-        </programlistingco>
+          </programlistingco>
+        </example>
 
-        <programlistingco role="XML">
+        <example>
+          <title>map-key-many-to-many</title>
+
+          <programlistingco role="XML">
             <areaspec>
-                <area id="indexmanytomany1" coords="2"/>
-                <area id="indexmanytomany2" coords="3"/>
-                <area id="indexmanytomany3" coords="3"/>
-             </areaspec>
-            <programlisting><![CDATA[<map-key-many-to-many
+              <area coords="2" id="indexmanytomany1" />
+
+              <area coords="3" id="indexmanytomany2" />
+
+              <area coords="3" id="indexmanytomany3" />
+            </areaspec>
+
+            <programlisting>&lt;map-key-many-to-many
         column="column_name"
         formula="any SQL expression"
         class="ClassName"
-/>]]></programlisting>
+/&gt;</programlisting>
+
             <calloutlist>
-                <callout arearefs="indexmanytomany1">
-                    <para>
-                        <literal>column</literal> (optional): the name of the foreign key
-                        column for the collection index values.
-                    </para>
-                </callout>
-                <callout arearefs="indexmanytomany2">
-                    <para>
-                        <literal>formula</literal> (optional): a SQ formula used to evaluate the
-                        foreign key of the map key.
-                    </para>
-                </callout>
-                <callout arearefs="indexmanytomany3">
-                    <para>
-                        <literal>class</literal> (required): the entity class used as the map key.
-                    </para>
-                </callout>
-            </calloutlist>
-        </programlistingco>
+              <callout arearefs="indexmanytomany1">
+                <para><literal>column</literal> (optional): the name of the
+                foreign key column for the collection index values.</para>
+              </callout>
 
+              <callout arearefs="indexmanytomany2">
+                <para><literal>formula</literal> (optional): a SQ formula used
+                to evaluate the foreign key of the map key.</para>
+              </callout>
 
-            <para>
-                If your table does not have an index column, and you still wish to use <literal>List</literal> 
-                as the property type, you can map the property as a Hibernate <emphasis>&lt;bag&gt;</emphasis>.
-                A bag does not retain its order when it is retrieved from the database, but it can be 
-                optionally sorted or ordered.
-            </para>
-            
-        </section>
+              <callout arearefs="indexmanytomany3">
+                <para><literal>class</literal> (required): the entity class
+                used as the map key.</para>
+              </callout>
+            </calloutlist>
+          </programlistingco>
+        </example>
+      </section>
+    </section>
 
     <section id="collections-ofvalues" revision="2">
-        <title>Collections of values and many-to-many associations</title>
+      <title>Collections of values</title>
 
-        <para>
-            Any collection of values or many-to-many associations requires a dedicated 
-            <emphasis>collection table</emphasis> with a foreign key column or columns, 
-            <emphasis>collection element column</emphasis> or columns, and possibly 
-            an index column or columns.
-        </para>
+      <para>In some situations you don't need to associate two entities but
+      simply create a collection of basic types or embeddable objects. Use the
+      <classname>@ElementCollection</classname> in this case.</para>
 
-        <para>
-            For a collection of values use the <literal>&lt;element&gt;</literal> tag. For example:
-        </para>
+      <example>
+        <title>Collection of basic types mapped via
+        <classname>@ElementCollection</classname></title>
 
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class User {
+   [...]
+   public String getLastname() { ...}
+
+   @ElementCollection
+   @CollectionTable(name="Nicknames", joinColumns=@JoinColumn(name="user_id"))
+   @Column(name="nickname")
+   public Set&lt;String&gt; getNicknames() { ... } 
+}</programlisting>
+      </example>
+
+      <para>The collection table holding the collection data is set using the
+      <classname>@CollectionTable</classname> annotation. If omitted the
+      collection table name default to the concatenation of the name of the
+      containing entity and the name of the collection attribute, separated by
+      an underscore. In our example, it would be
+      <literal>User_nicknames</literal>.</para>
+
+      <para>The column holding the basic type is set using the
+      <classname>@Column</classname> annotation. If omitted, the column name
+      defaults to the property name: in our example, it would be
+      <literal>nicknames</literal>.</para>
+
+      <para>But you are not limited to basic types, the collection type can be
+      any embeddable object. To override the columns of the embeddable object
+      in the collection table, use the
+      <classname>@AttributeOverride</classname> annotation.</para>
+
+      <example>
+        <title>@ElementCollection for embeddable objects</title>
+
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class User {
+   [...]
+   public String getLastname() { ...}
+
+   @ElementCollection
+   @CollectionTable(name="Addresses", joinColumns=@JoinColumn(name="user_id"))
+   @AttributeOverrides({
+      @AttributeOverride(name="street1", column=@Column(name="fld_street"))
+   })
+   public Set&lt;Address&gt; getAddresses() { ... } 
+}
+
+ at Embeddable
+public class Address {
+   public String getStreet1() {...}
+   [...]
+}</programlisting>
+      </example>
+
+      <para>Such an embeddable object cannot contains a collection
+      itself.</para>
+
+      <note>
+        <para>in <classname>@AttributeOverride</classname>, you must use the
+        <literal>value.</literal> prefix to override properties of the
+        embeddable object used in the map value and the
+        <literal>key.</literal> prefix to override properties of the
+        embeddable object used in the map key.</para>
+
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class User {
+   @ElementCollection
+   @AttributeOverrides({
+      @AttributeOverride(name="key.street1", column=@Column(name="fld_street")),
+      @AttributeOverride(name="value.stars", column=@Column(name="fld_note"))
+   })
+   public Map&lt;Address,Rating&gt; getFavHomes() { ... }</programlisting>
+      </note>
+
+      <note>
+        <para>We recommend you to migrate from
+        <classname>@org.hibernate.annotations.CollectionOfElements</classname>
+        to the new <classname>@ElementCollection</classname>
+        annotation.</para>
+      </note>
+
+      <para>Using the mapping file approach a collection of values is mapped
+      using the <literal>&lt;element&gt;</literal> tag. For example:</para>
+
+      <example>
+        <title>&lt;element&gt; tag for collection values using mapping
+        files</title>
+
         <programlistingco role="XML">
-            <areaspec>
-                <area id="element1b" coords="2"/>
-                <area id="element2b" coords="3"/>
-                <area id="element3b" coords="4"/>
-             </areaspec>
-            <programlisting><![CDATA[<element
+          <areaspec>
+            <area coords="2" id="element1b" />
+
+            <area coords="3" id="element2b" />
+
+            <area coords="4" id="element3b" />
+          </areaspec>
+
+          <programlisting>&lt;element
         column="column_name"
         formula="any SQL expression"
         type="typename"
@@ -475,612 +971,575 @@
         not-null="true|false"
         unique="true|false"
         node="element-name"
-/>]]></programlisting>
-            <calloutlist>
-                <callout arearefs="element1b">
-                    <para>
-                        <literal>column</literal> (optional): the name of the column holding the
-                        collection element values.
-                    </para>
-                </callout>
-                <callout arearefs="element2b">
-                    <para>
-                        <literal>formula</literal> (optional): an SQL formula used to evaluate the
-                        element.
-                    </para>
-                </callout>
-                <callout arearefs="element3b">
-                    <para>
-                        <literal>type</literal> (required): the type of the collection element.
-                    </para>
-                </callout>
-            </calloutlist>
-        </programlistingco>
+/&gt;</programlisting>
 
-        <para>
-            A <emphasis>many-to-many association</emphasis> is specified using the 
-            <literal>&lt;many-to-many&gt;</literal> element.
-        </para>
+          <calloutlist>
+            <callout arearefs="element1b">
+              <para><literal>column</literal> (optional): the name of the
+              column holding the collection element values.</para>
+            </callout>
 
-        <programlistingco role="XML">
-            <areaspec>
-                <area id="manytomany1" coords="2"/>
-                <area id="manytomany2" coords="3"/>
-                <area id="manytomany3" coords="4"/>
-                <area id="manytomany4" coords="5"/>
-                <area id="manytomany5" coords="6"/>
-                <area id="manytomany6" coords="7"/>
-                <area id="manytomany7" coords="8"/>
-                <area id="manytomany8" coords="9"/>
-            </areaspec>
-            <programlisting><![CDATA[<many-to-many
-        column="column_name"
-        formula="any SQL expression"
-        class="ClassName"
-        fetch="select|join"
-        unique="true|false"
-        not-found="ignore|exception"
-        entity-name="EntityName"
-        property-ref="propertyNameFromAssociatedClass"
-        node="element-name"
-        embed-xml="true|false"
-    />]]></programlisting>
-            <calloutlist>
-                <callout arearefs="manytomany1">
-                    <para>
-                        <literal>column</literal> (optional): the name of the element foreign key column.
-                    </para>
-                </callout>
-                <callout arearefs="manytomany2">
-                    <para>
-                        <literal>formula</literal> (optional): an SQL formula used to evaluate the element
-                        foreign key value.
-                    </para>
-                </callout>
-                <callout arearefs="manytomany3">
-                    <para>
-                        <literal>class</literal> (required): the name of the associated class.
-                    </para>
-                </callout>
-                <callout arearefs="manytomany4">
-                    <para>
-                        <literal>fetch</literal> (optional - defaults to <literal>join</literal>):
-                        enables outer-join or sequential select fetching for this association. This
-                        is a special case; for full eager fetching in a single <literal>SELECT</literal>
-                        of an entity and its many-to-many relationships to other entities, you would
-                        enable <literal>join</literal> fetching,not only of the collection itself,
-                        but also with this attribute on the <literal>&lt;many-to-many&gt;</literal>
-                        nested element.
-                    </para>
-                </callout>
-                <callout arearefs="manytomany5">
-                    <para>
-                        <literal>unique</literal> (optional): enables the DDL generation of a unique
-                        constraint for the foreign-key column. This makes the association multiplicity
-                        effectively one-to-many.
-                    </para>
-                </callout>
-	            <callout arearefs="manytomany6">
-	                <para>
-	                    <literal>not-found</literal> (optional - defaults to <literal>exception</literal>): 
-	                    specifies how foreign keys that reference missing rows will be handled: 
-	                    <literal>ignore</literal> will treat a missing row as a null association.
-	                </para>
-	            </callout>
-                <callout arearefs="manytomany7">
-                    <para>
-                        <literal>entity-name</literal> (optional): the entity name of the associated class,
-                        as an alternative to <literal>class</literal>.
-                    </para>
-                </callout>
-                <callout arearefs="manytomany8">
-                    <para>
-                        <literal>property-ref</literal> (optional): the name of a property of the associated 
-                        class that is joined to this foreign key. If not specified, the primary key of
-                        the associated class is used.
-                    </para>                
-                </callout>                   
-            </calloutlist>
+            <callout arearefs="element2b">
+              <para><literal>formula</literal> (optional): an SQL formula used
+              to evaluate the element.</para>
+            </callout>
+
+            <callout arearefs="element3b">
+              <para><literal>type</literal> (required): the type of the
+              collection element.</para>
+            </callout>
+          </calloutlist>
         </programlistingco>
+      </example>
+    </section>
+  </section>
 
-	<para>
-		Here are some examples.
-	</para>
-        <para>
-            A set of strings:
-        </para>
+  <section id="collections-advancedmappings">
+    <title>Advanced collection mappings</title>
 
-        <programlisting role="XML"><![CDATA[<set name="names" table="person_names">
-    <key column="person_id"/>
-    <element column="person_name" type="string"/>
-</set>]]></programlisting>
+    <section id="collections-sorted" revision="2">
+      <title id="section.sorted.collections">Sorted collections</title>
 
-        <para>
-            A bag containing integers with an iteration order determined by the
-            <literal>order-by</literal> attribute:
-        </para>
+      <para>Hibernate supports collections implementing
+      <literal>java.util.SortedMap</literal> and
+      <literal>java.util.SortedSet</literal>. With annotations you declare a
+      sort comparator using <literal>@Sort</literal>. You between the
+      comparator types unsorted, natural or custom. If you want to use your
+      own comparator implementation, you'll also have to express the
+      implementation class using the <literal>comparator</literal> attribute.
+      Note that you need to use either a <classname>SortedSet</classname> or a
+      <classname>SortedMap</classname> interface.</para>
 
-        <programlisting role="XML"><![CDATA[<bag name="sizes"
-        table="item_sizes" 
-        order-by="size asc">
-    <key column="item_id"/>
-    <element column="size" type="integer"/>
-</bag>]]></programlisting>
+      <example>
+        <title>Sorted collection with @Sort</title>
 
-        <para>
-            An array of entities, in this case, a many-to-many association:
-        </para>
+        <programlisting language="JAVA" role="JAVA">@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
+ at JoinColumn(name="CUST_ID")
+ at Sort(type = SortType.COMPARATOR, comparator = TicketComparator.class)
+ at Where(clause="1=1")
+ at OnDelete(action=OnDeleteAction.CASCADE)
+public SortedSet&lt;Ticket&gt; getTickets() {
+    return tickets;
+}</programlisting>
+      </example>
 
-        <programlisting role="XML"><![CDATA[<array name="addresses"
-        table="PersonAddress" 
-        cascade="persist">
-    <key column="personId"/>
-    <list-index column="sortOrder"/>
-    <many-to-many column="addressId" class="Address"/>
-</array>]]></programlisting>
+      <para>Using Hibernate mapping files you specify a comparator in the
+      mapping file with <literal>&lt;sort&gt;</literal>:</para>
 
-        <para>
-            A map from string indices to dates:
-        </para>
+      <example>
+        <title>Sorted collection using xml mapping</title>
 
-        <programlisting role="XML"><![CDATA[<map name="holidays"
-        table="holidays" 
-        schema="dbo" 
-        order-by="hol_name asc">
-    <key column="id"/>
-    <map-key column="hol_name" type="string"/>
-    <element column="hol_date" type="date"/>
-</map>]]></programlisting>
+        <programlisting role="XML">&lt;set name="aliases"
+            table="person_aliases" 
+            sort="natural"&gt;
+    &lt;key column="person"/&gt;
+    &lt;element column="name" type="string"/&gt;
+&lt;/set&gt;
 
-        <para>
-            A list of components (this is discussed in the next chapter):
-        </para>
+&lt;map name="holidays" sort="my.custom.HolidayComparator"&gt;
+    &lt;key column="year_id"/&gt;
+    &lt;map-key column="hol_name" type="string"/&gt;
+    &lt;element column="hol_date" type="date"/&gt;
+&lt;/map&gt;</programlisting>
+      </example>
 
-        <programlisting role="XML"><![CDATA[<list name="carComponents"
-        table="CarComponents">
-    <key column="carId"/>
-    <list-index column="sortOrder"/>
-    <composite-element class="CarComponent">
-        <property name="price"/>
-        <property name="type"/>
-        <property name="serialNumber" column="serialNum"/>
-    </composite-element>
-</list>]]></programlisting>
+      <para>Allowed values of the <literal>sort</literal> attribute are
+      <literal>unsorted</literal>, <literal>natural</literal> and the name of
+      a class implementing <literal>java.util.Comparator</literal>.</para>
 
+      <para>Sorted collections actually behave like
+      <literal>java.util.TreeSet</literal> or
+      <literal>java.util.TreeMap</literal>.</para>
+
+      <para>If you want the database itself to order the collection elements,
+      use the <literal>order-by</literal> attribute of <literal>set</literal>,
+      <literal>bag</literal> or <literal>map</literal> mappings. This solution
+      is only available under JDK 1.4 or higher and is implemented using
+      <literal>LinkedHashSet</literal> or <literal>LinkedHashMap</literal>.
+      This performs the ordering in the SQL query and not in the
+      memory.</para>
+
+      <example>
+        <title>Sorting in database using order-by</title>
+
+        <programlisting role="XML">&lt;set name="aliases" table="person_aliases" order-by="lower(name) asc"&gt;
+    &lt;key column="person"/&gt;
+    &lt;element column="name" type="string"/&gt;
+&lt;/set&gt;
+
+&lt;map name="holidays" order-by="hol_date, hol_name"&gt;
+    &lt;key column="year_id"/&gt;
+    &lt;map-key column="hol_name" type="string"/&gt;
+    &lt;element column="hol_date type="date"/&gt;
+&lt;/map&gt;</programlisting>
+      </example>
+
+      <note>
+        <title>Note</title>
+
+        <para>The value of the <literal>order-by</literal> attribute is an SQL
+        ordering, not an HQL ordering.</para>
+      </note>
+
+      <para>Associations can even be sorted by arbitrary criteria at runtime
+      using a collection <literal>filter()</literal>:</para>
+
+      <example>
+        <title>Sorting via a query filter</title>
+
+        <programlisting role="JAVA">sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();</programlisting>
+      </example>
     </section>
 
-    <section id="collections-onetomany">
-        <title>One-to-many associations</title>
+    <section id="collections-bidirectional" revision="1">
+      <title>Bidirectional associations</title>
 
-        <para>
-            A <emphasis>one-to-many association</emphasis> links the tables of two classes
-            via a foreign key with no intervening collection table. This mapping loses 
-            certain semantics of normal Java collections:
-        </para>
+      <para>A <emphasis>bidirectional association</emphasis> allows navigation
+      from both "ends" of the association. Two kinds of bidirectional
+      association are supported: <variablelist>
+          <varlistentry>
+            <term>one-to-many</term>
 
-        <itemizedlist spacing="compact">
             <listitem>
-                <para>
-                    An instance of the contained entity class cannot belong to more than
-                    one instance of the collection.
-                </para>
+              <para>set or bag valued at one end and single-valued at the
+              other</para>
             </listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term>many-to-many</term>
+
             <listitem>
-                <para>
-                    An instance of the contained entity class cannot appear at more than
-                    one value of the collection index.
-                </para>
+              <para>set or bag valued at both ends</para>
             </listitem>
-        </itemizedlist>
+          </varlistentry>
+        </variablelist></para>
 
-        <para>
-            An association from <literal>Product</literal> to <literal>Part</literal> requires 
-            the existence of a foreign key column and possibly an index column to the <literal>Part</literal> 
-            table. A <literal>&lt;one-to-many&gt;</literal> tag indicates that this is a one-to-many 
-            association.
-        </para>
+      <para>Often there exists a many to one association which is the owner
+      side of a bidirectional relationship. The corresponding one to many
+      association is in this case annotated by
+      <literal>@OneToMany(mappedBy=...)</literal></para>
 
-        <programlistingco role="XML">
-            <areaspec>
-                <area id="onetomany1" coords="2"/>
-                <area id="onetomany2" coords="3"/>
-                <area id="onetomany3" coords="4"/>
-            </areaspec>
-            <programlisting><![CDATA[<one-to-many
-        class="ClassName"
-        not-found="ignore|exception"
-        entity-name="EntityName"
-        node="element-name"
-        embed-xml="true|false"
-    />]]></programlisting>
-            <calloutlist>
-                <callout arearefs="onetomany1">
-                    <para>
-                        <literal>class</literal> (required): the name of the associated class.
-                    </para>
-                </callout>
-		        <callout arearefs="onetomany2">
-		            <para>
-		                <literal>not-found</literal> (optional - defaults to <literal>exception</literal>): 
-		                specifies how cached identifiers that reference missing rows will be handled.
-		                <literal>ignore</literal> will treat a missing row as a null association.
-		            </para>
-		        </callout>
-                <callout arearefs="onetomany3">
-                    <para>
-                        <literal>entity-name</literal> (optional): the entity name of the associated class,
-                        as an alternative to <literal>class</literal>.
-                    </para>
-                </callout>
-            </calloutlist>
-       </programlistingco>
-  
-        <para>
-            The <literal>&lt;one-to-many&gt;</literal> element does not need to
-            declare any columns. Nor is it necessary to specify the <literal>table</literal>
-            name anywhere.
-        </para>
+      <example>
+        <title>Bidirectional one to many with many to one side as association
+        owner</title>
 
-	<warning>  
-	<para>
-            If the foreign key column of a 
-            <literal>&lt;one-to-many&gt;</literal> association is declared <literal>NOT NULL</literal>, 
-            you must declare the <literal>&lt;key&gt;</literal> mapping 
-            <literal>not-null="true"</literal> or <emphasis>use a bidirectional association</emphasis> 
-            with the collection mapping marked <literal>inverse="true"</literal>. See the discussion 
-            of bidirectional associations later in this chapter for more information.
-        </para>
-     	</warning>
-   
-        <para>
-            The following example shows a map of <literal>Part</literal> entities by name, where
-            <literal>partName</literal> is a persistent property of <literal>Part</literal>.
-            Notice the use of a formula-based index:
-        </para>
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class Troop {
+    @OneToMany(mappedBy="troop")
+    public Set&lt;Soldier&gt; getSoldiers() {
+    ...
+}
 
-        <programlisting role="XML"><![CDATA[<map name="parts"
-        cascade="all">
-    <key column="productId" not-null="true"/>
-    <map-key formula="partName"/>
-    <one-to-many class="Part"/>
-</map>]]></programlisting>
-    </section>
-    
-    </section>
+ at Entity
+public class Soldier {
+    @ManyToOne
+    @JoinColumn(name="troop_fk")
+    public Troop getTroop() {
+    ...
+}           </programlisting>
+      </example>
 
-    <section id="collections-advancedmappings">
-        <title>Advanced collection mappings</title>
+      <para><classname>Troop</classname> has a bidirectional one to many
+      relationship with <literal>Soldier</literal> through the
+      <literal>troop</literal> property. You don't have to (must not) define
+      any physical mapping in the <literal>mappedBy</literal> side.</para>
 
-    <section id="collections-sorted" revision="2">
-        <title>Sorted collections</title>
+      <para>To map a bidirectional one to many, with the one-to-many side as
+      the owning side, you have to remove the <literal>mappedBy</literal>
+      element and set the many to one <literal>@JoinColumn</literal> as
+      insertable and updatable to false. This solution is not optimized and
+      will produce additional UPDATE statements.</para>
 
-        <para>
-            Hibernate supports collections implementing <literal>java.util.SortedMap</literal> and
-            <literal>java.util.SortedSet</literal>. You must specify a comparator in the mapping file:
-        </para>
+      <example>
+        <title>Bidirectional associtaion with one to many side as
+        owner</title>
 
-        <programlisting role="XML"><![CDATA[<set name="aliases"
-            table="person_aliases" 
-            sort="natural">
-    <key column="person"/>
-    <element column="name" type="string"/>
-</set>
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class Troop {
+    @OneToMany
+    @JoinColumn(name="troop_fk") //we need to duplicate the physical information
+    public Set&lt;Soldier&gt; getSoldiers() {
+    ...
+}
 
-<map name="holidays" sort="my.custom.HolidayComparator">
-    <key column="year_id"/>
-    <map-key column="hol_name" type="string"/>
-    <element column="hol_date" type="date"/>
-</map>]]></programlisting>
+ at Entity
+public class Soldier {
+    @ManyToOne
+    @JoinColumn(name="troop_fk", insertable=false, updatable=false)
+    public Troop getTroop() {
+    ...
+}</programlisting>
+      </example>
 
-        <para>
-            Allowed values of the <literal>sort</literal> attribute are <literal>unsorted</literal>,
-            <literal>natural</literal> and the name of a class implementing
-            <literal>java.util.Comparator</literal>.
-        </para>
+      <para>Again a look at the maping file approach. There you can define a
+      bidirectional one-to-many association by mapping a one-to-many
+      association to the same table column(s) as a many-to-one association and
+      declaring the many-valued end <literal>inverse="true"</literal>.</para>
 
-        <para>
-            Sorted collections actually behave like <literal>java.util.TreeSet</literal> or
-            <literal>java.util.TreeMap</literal>.
-        </para>
+      <example>
+        <title>Bidirectional one to many via Hibernate mapping files</title>
 
-        <para>
-            If you want the database itself to order the collection elements, use the
-            <literal>order-by</literal> attribute of <literal>set</literal>, <literal>bag</literal>
-            or <literal>map</literal> mappings. This solution is only available under
-            JDK 1.4 or higher and is implemented using <literal>LinkedHashSet</literal> or
-            <literal>LinkedHashMap</literal>. This performs the ordering in the SQL query and 
-            not in the memory.
-        </para>
+        <programlisting role="XML">&lt;class name="Parent"&gt;
+    &lt;id name="id" column="parent_id"/&gt;
+    ....
+    &lt;set name="children" inverse="true"&gt;
+        &lt;key column="parent_id"/&gt;
+        &lt;one-to-many class="Child"/&gt;
+    &lt;/set&gt;
+&lt;/class&gt;
 
-        <programlisting role="XML"><![CDATA[<set name="aliases" table="person_aliases" order-by="lower(name) asc">
-    <key column="person"/>
-    <element column="name" type="string"/>
-</set>
+&lt;class name="Child"&gt;
+    &lt;id name="id" column="child_id"/&gt;
+    ....
+    &lt;many-to-one name="parent" 
+        class="Parent" 
+        column="parent_id"
+        not-null="true"/&gt;
+&lt;/class&gt;</programlisting>
+      </example>
 
-<map name="holidays" order-by="hol_date, hol_name">
-    <key column="year_id"/>
-    <map-key column="hol_name" type="string"/>
-    <element column="hol_date type="date"/>
-</map>]]></programlisting>
+      <para>Mapping one end of an association with
+      <literal>inverse="true"</literal> does not affect the operation of
+      cascades as these are orthogonal concepts.</para>
 
-        <note>
-	<title>Note</title>
-	<para>
-            The value of the <literal>order-by</literal> attribute is an SQL ordering, not
-            an HQL ordering.
-        </para>
-	</note>
+      <para>A many-to-many association is defined logically using the
+      <literal>@ManyToMany</literal> annotation. You also have to describe the
+      association table and the join conditions using the
+      <literal>@JoinTable</literal> annotation. If the association is
+      bidirectional, one side has to be the owner and one side has to be the
+      inverse end (ie. it will be ignored when updating the relationship
+      values in the association table):</para>
 
-        <para>
-            Associations can even be sorted by arbitrary criteria at runtime using a collection
-            <literal>filter()</literal>:
-        </para>
+      <example>
+        <title>Many to many association via @ManyToMany</title>
 
-        <programlisting role="JAVA"><![CDATA[sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();]]></programlisting>
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class Employer implements Serializable {
+    @ManyToMany(
+        targetEntity=org.hibernate.test.metadata.manytomany.Employee.class,
+        cascade={CascadeType.PERSIST, CascadeType.MERGE}
+    )
+    @JoinTable(
+        name="EMPLOYER_EMPLOYEE",
+        joinColumns=@JoinColumn(name="EMPER_ID"),
+        inverseJoinColumns=@JoinColumn(name="EMPEE_ID")
+    )
+    public Collection getEmployees() {
+        return employees;
+    }
+    ...
+}              </programlisting>
 
-    </section>
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class Employee implements Serializable {
+    @ManyToMany(
+        cascade = {CascadeType.PERSIST, CascadeType.MERGE},
+        mappedBy = "employees",
+        targetEntity = Employer.class
+    )
+    public Collection getEmployers() {
+        return employers;
+    }
+}                </programlisting>
+      </example>
 
-     <section id="collections-bidirectional" revision="1">
-        <title>Bidirectional associations</title>
+      <para>We've already shown the many declarations and the detailed
+      attributes for associations. We'll go deeper in the
+      <literal>@JoinTable</literal> description, it defines a
+      <literal>name</literal>, an array of join columns, and an array of
+      inverse join columns. The latter ones are the columns of the association
+      table which refer to the <classname>Employee</classname> primary key
+      (the "other side"). As seen previously, the other side don't have to
+      (must not) describe the physical mapping: a simple
+      <literal>mappedBy</literal> argument containing the owner side property
+      name bind the two.</para>
 
-        <para>
-            A <emphasis>bidirectional association</emphasis> allows navigation from both
-            "ends" of the association. Two kinds of bidirectional association are
-            supported:
+      <para>As any other annotations, most values are guessed in a many to
+      many relationship. Without describing any physical mapping in a
+      unidirectional many to many the following rules applied. The table name
+      is the concatenation of the owner table name, <keycap>_</keycap> and the
+      other side table name. The foreign key name(s) referencing the owner
+      table is the concatenation of the owner table name, <keycap>_</keycap>
+      and the owner primary key column(s). The foreign key name(s) referencing
+      the other side is the concatenation of the owner property name,
+      <keycap>_</keycap>, and the other side primary key column(s). These are
+      the same rules used for a unidirectional one to many
+      relationship.</para>
 
-            <variablelist>
-                <varlistentry>
-                    <term>one-to-many</term>
-                    <listitem>
-                        <para>
-                            set or bag valued at one end and single-valued at the other
-                        </para>
-                    </listitem>
-                </varlistentry>
-                <varlistentry>
-                    <term>many-to-many</term>
-                    <listitem>
-                        <para>
-                            set or bag valued at both ends
-                        </para>
-                    </listitem>
-                </varlistentry>
-            </variablelist>
+      <example>
+        <title>Default values for <classname>@ManyToMany</classname>
+        (uni-directional)</title>
 
-        </para>
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class Store {
+    @ManyToMany(cascade = CascadeType.PERSIST)
+    public Set&lt;City&gt; getImplantedIn() {
+        ...
+    }
+}
 
-        <para>
-            You can specify a bidirectional many-to-many association by mapping two
-            many-to-many associations to the same database table and declaring one end as
-            <emphasis>inverse</emphasis>. You cannot select an
-            indexed collection.
-        </para>
+ at Entity
+public class City {
+    ... //no bidirectional relationship
+}             </programlisting>
+      </example>
 
-        <para>
-            Here is an example of a bidirectional many-to-many association that illustrates how each category can
-            have many items and each item can be in many categories:
-        </para>
+      <para>A <literal>Store_City</literal> is used as the join table. The
+      <literal>Store_id</literal> column is a foreign key to the
+      <literal>Store</literal> table. The <literal>implantedIn_id</literal>
+      column is a foreign key to the <literal>City</literal> table.</para>
 
-        <programlisting role="XML"><![CDATA[<class name="Category">
-    <id name="id" column="CATEGORY_ID"/>
+      <para>Without describing any physical mapping in a bidirectional many to
+      many the following rules applied. The table name is the concatenation of
+      the owner table name, <keycap>_</keycap> and the other side table name.
+      The foreign key name(s) referencing the owner table is the concatenation
+      of the other side property name, <keycap>_</keycap>, and the owner
+      primary key column(s). The foreign key name(s) referencing the other
+      side is the concatenation of the owner property name,
+      <keycap>_</keycap>, and the other side primary key column(s). These are
+      the same rules used for a unidirectional one to many
+      relationship.</para>
+
+      <example>
+        <title>Default values for <classname>@ManyToMany</classname>
+        (bi-directional)</title>
+
+        <programlisting language="JAVA" role="JAVA">@Entity
+public class Store {
+    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
+    public Set&lt;Customer&gt; getCustomers() {
+        ...
+    }
+}
+
+ at Entity
+public class Customer {
+    @ManyToMany(mappedBy="customers")
+    public Set&lt;Store&gt; getStores() {
+        ...
+    }
+}             </programlisting>
+      </example>
+
+      <para>A <literal>Store_Customer</literal> is used as the join table. The
+      <literal>stores_id</literal> column is a foreign key to the
+      <literal>Store</literal> table. The <literal>customers_id</literal>
+      column is a foreign key to the <literal>Customer</literal> table.</para>
+
+      <para>Using Hibernate mapping files you can map a bidirectional
+      many-to-many association by mapping two many-to-many associations to the
+      same database table and declaring one end as
+      <emphasis>inverse</emphasis>. <note>
+          <para>You cannot select an indexed collection.</para>
+        </note></para>
+
+      <para>Here is an example of a bidirectional many-to-many association
+      that illustrates how each category can have many items and each item can
+      be in many categories:</para>
+
+      <example>
+        <title>Many to many association using Hibernate mapping files</title>
+
+        <programlisting role="XML">&lt;class name="Category"&gt;
+    &lt;id name="id" column="CATEGORY_ID"/&gt;
     ...
-    <bag name="items" table="CATEGORY_ITEM">
-        <key column="CATEGORY_ID"/>
-        <many-to-many class="Item" column="ITEM_ID"/>
-    </bag>
-</class>
+    &lt;bag name="items" table="CATEGORY_ITEM"&gt;
+        &lt;key column="CATEGORY_ID"/&gt;
+        &lt;many-to-many class="Item" column="ITEM_ID"/&gt;
+    &lt;/bag&gt;
+&lt;/class&gt;
 
-<class name="Item">
-    <id name="id" column="ITEM_ID"/>
+&lt;class name="Item"&gt;
+    &lt;id name="id" column="ITEM_ID"/&gt;
     ...
 
-    <!-- inverse end -->
-    <bag name="categories" table="CATEGORY_ITEM" inverse="true">
-        <key column="ITEM_ID"/>
-        <many-to-many class="Category" column="CATEGORY_ID"/>
-    </bag>
-</class>]]></programlisting>
+    &lt;!-- inverse end --&gt;
+    &lt;bag name="categories" table="CATEGORY_ITEM" inverse="true"&gt;
+        &lt;key column="ITEM_ID"/&gt;
+        &lt;many-to-many class="Category" column="CATEGORY_ID"/&gt;
+    &lt;/bag&gt;
+&lt;/class&gt;</programlisting>
+      </example>
 
-        <para>
-            Changes made only to the inverse end of the association are <emphasis>not</emphasis>
-            persisted. This means that Hibernate has two representations in memory for every
-            bidirectional association: one link from A to B and another link from B to A. This
-            is easier to understand if you think about the Java object model and how
-            a many-to-many relationship in Javais created:
-        </para>
+      <para>Changes made only to the inverse end of the association are
+      <emphasis>not</emphasis> persisted. This means that Hibernate has two
+      representations in memory for every bidirectional association: one link
+      from A to B and another link from B to A. This is easier to understand
+      if you think about the Java object model and how a many-to-many
+      relationship in Javais created:</para>
 
-        <programlisting role="JAVA"><![CDATA[
-category.getItems().add(item);          // The category now "knows" about the relationship
-item.getCategories().add(category);     // The item now "knows" about the relationship
+      <example>
+        <title>Effect of inverse vs. non-inverse side of many to many
+        associations</title>
 
+        <programlisting role="JAVA">category.getItems().add(item);           // The category now "knows" about the relationship
+item.getCategories().add(category);      // The item now "knows" about the relationship
+
 session.persist(item);                   // The relationship won't be saved!
-session.persist(category);               // The relationship will be saved]]></programlisting>
+session.persist(category);               // The relationship will be saved</programlisting>
+      </example>
 
-        <para>
-            The non-inverse side is used to save the in-memory representation to the database.
-        </para>
+      <para>The non-inverse side is used to save the in-memory representation
+      to the database.</para>
+    </section>
 
-        <para>
-            You can define a bidirectional one-to-many association by mapping a one-to-many association
-            to the same table column(s) as a many-to-one association and declaring the many-valued
-            end <literal>inverse="true"</literal>.
-        </para>
+    <section id="collections-indexedbidirectional">
+      <title>Bidirectional associations with indexed collections</title>
 
-        <programlisting role="XML"><![CDATA[<class name="Parent">
-    <id name="id" column="parent_id"/>
-    ....
-    <set name="children" inverse="true">
-        <key column="parent_id"/>
-        <one-to-many class="Child"/>
-    </set>
-</class>
+      <para>Here are some additional consideration for bidirectional mappings
+      with indexed collections using Hibernate mapping files. Refer also to
+      <xref linkend="section.indexed.collections" /> and <xref
+      linkend="section.sorted.collections" />.</para>
 
-<class name="Child">
-    <id name="id" column="child_id"/>
-    ....
-    <many-to-one name="parent" 
-        class="Parent" 
-        column="parent_id"
-        not-null="true"/>
-</class>]]></programlisting>
+      <para>A bidirectional association where one end is represented as a
+      <literal>&lt;list&gt;</literal> or <literal>&lt;map&gt;</literal>,
+      requires special consideration. If there is a property of the child
+      class that maps to the index column you can use
+      <literal>inverse="true"</literal> on the collection mapping:</para>
 
-        <para>
-            Mapping one end of an association with <literal>inverse="true"</literal> does not
-            affect the operation of cascades as these are orthogonal concepts.
-        </para>
+      <example>
+        <title>Bidirectional association with indexed collection</title>
 
-    </section>
-
-    <section id="collections-indexedbidirectional">
-        <title>Bidirectional associations with indexed collections</title>
-        <para>
-            A bidirectional association where one end is represented as a <literal>&lt;list&gt;</literal>
-            or <literal>&lt;map&gt;</literal>, requires special consideration. If there is a property of
-            the child class that maps to the index column you can use 
-            <literal>inverse="true"</literal> on the collection mapping:
-        </para>
-        
-        <programlisting role="XML"><![CDATA[<class name="Parent">
-    <id name="id" column="parent_id"/>
+        <programlisting role="XML">&lt;class name="Parent"&gt;
+    &lt;id name="id" column="parent_id"/&gt;
     ....
-    <map name="children" inverse="true">
-        <key column="parent_id"/>
-        <map-key column="name" 
-            type="string"/>
-        <one-to-many class="Child"/>
-    </map>
-</class>
+    &lt;map name="children" inverse="true"&gt;
+        &lt;key column="parent_id"/&gt;
+        &lt;map-key column="name" 
+            type="string"/&gt;
+        &lt;one-to-many class="Child"/&gt;
+    &lt;/map&gt;
+&lt;/class&gt;
 
-<class name="Child">
-    <id name="id" column="child_id"/>
+&lt;class name="Child"&gt;
+    &lt;id name="id" column="child_id"/&gt;
     ....
-    <property name="name" 
-        not-null="true"/>
-    <many-to-one name="parent" 
+    &lt;property name="name" 
+        not-null="true"/&gt;
+    &lt;many-to-one name="parent" 
         class="Parent" 
         column="parent_id"
-        not-null="true"/>
-</class>]]></programlisting>
+        not-null="true"/&gt;
+&lt;/class&gt;</programlisting>
+      </example>
 
-        <para>
-            If there is no such property on the child class, the association cannot be considered
-            truly bidirectional. That is, there is information available at one end of the association that is
-            not available at the other end. In this case, you cannot map the collection 
-            <literal>inverse="true"</literal>. Instead, you could use the following mapping:
-        </para>
+      <para>If there is no such property on the child class, the association
+      cannot be considered truly bidirectional. That is, there is information
+      available at one end of the association that is not available at the
+      other end. In this case, you cannot map the collection
+      <literal>inverse="true"</literal>. Instead, you could use the following
+      mapping:</para>
 
-        <programlisting role="XML"><![CDATA[<class name="Parent">
-    <id name="id" column="parent_id"/>
+      <example>
+        <title>Bidirectional association with indexed collection, but no index
+        column</title>
+
+        <programlisting role="XML">&lt;class name="Parent"&gt;
+    &lt;id name="id" column="parent_id"/&gt;
     ....
-    <map name="children">
-        <key column="parent_id"
-            not-null="true"/>
-        <map-key column="name" 
-            type="string"/>
-        <one-to-many class="Child"/>
-    </map>
-</class>
+    &lt;map name="children"&gt;
+        &lt;key column="parent_id"
+            not-null="true"/&gt;
+        &lt;map-key column="name" 
+            type="string"/&gt;
+        &lt;one-to-many class="Child"/&gt;
+    &lt;/map&gt;
+&lt;/class&gt;
 
-<class name="Child">
-    <id name="id" column="child_id"/>
+&lt;class name="Child"&gt;
+    &lt;id name="id" column="child_id"/&gt;
     ....
-    <many-to-one name="parent" 
+    &lt;many-to-one name="parent" 
         class="Parent" 
         column="parent_id"
         insert="false"
         update="false"
-        not-null="true"/>
-</class>]]></programlisting>
+        not-null="true"/&gt;
+&lt;/class&gt;</programlisting>
+      </example>
 
-       <para>
-           Note that in this mapping, the collection-valued end of the association is responsible for 
-           updates to the foreign key. <!--TODO: Does this really result in some unnecessary update statements?-->
-       </para>
+      <para>Note that in this mapping, the collection-valued end of the
+      association is responsible for updates to the foreign key.<!--TODO: Does this really result in some unnecessary update statements?--></para>
+    </section>
 
-    </section>
-    
     <section id="collections-ternary">
-        <title>Ternary associations</title>
+      <title>Ternary associations</title>
 
-        <para>
-            There are three possible approaches to mapping a ternary association. One approach is to use a 
-            <literal>Map</literal> with an association as its index:
-        </para>
+      <para>There are three possible approaches to mapping a ternary
+      association. One approach is to use a <literal>Map</literal> with an
+      association as its index:</para>
 
-        <programlisting role="XML"><![CDATA[<map name="contracts">
-    <key column="employer_id" not-null="true"/>
-    <map-key-many-to-many column="employee_id" class="Employee"/>
-    <one-to-many class="Contract"/>
-</map>]]></programlisting>
-            
-            <programlisting role="XML"><![CDATA[<map name="connections">
-    <key column="incoming_node_id"/>
-    <map-key-many-to-many column="outgoing_node_id" class="Node"/>
-    <many-to-many column="connection_id" class="Connection"/>
-</map>]]></programlisting>
-            
-        <para>
-            A second approach is to remodel the association as an entity class. This
-            is the most common approach.
-        </para>
-        
-        <para>
-            A final alternative is to use composite elements, which will be discussed later. 
-        </para>
-        
+      <example>
+        <title>Ternary association mapping</title>
+
+        <programlisting role="XML">@Entity
+public class Company {
+   @Id 
+   int id;
+   ...
+   @OneToMany // unidirectional
+   @MapKeyJoinColumn(name="employee_id")
+   Map&lt;Employee, Contract&gt; contracts;
+}
+
+// or
+
+&lt;map name="contracts"&gt;
+    &lt;key column="employer_id" not-null="true"/&gt;
+    &lt;map-key-many-to-many column="employee_id" class="Employee"/&gt;
+    &lt;one-to-many class="Contract"/&gt;
+&lt;/map&gt;</programlisting>
+      </example>
+
+      <para>A second approach is to remodel the association as an entity
+      class. This is the most common approach. A final alternative is to use
+      composite elements, which will be discussed later.</para>
     </section>
-    
+
     <section id="collections-idbag" revision="1">
-        <title><literal>Using an &lt;idbag&gt;</literal></title>
+      <title><literal>Using an &lt;idbag&gt;</literal></title>
 
-        <para>
-            The majority of the many-to-many associations and collections of values
-            shown previously all map to tables with composite keys, even though it has been have suggested 
-	    that entities should have synthetic identifiers (surrogate keys). A
-            pure association table does not seem to benefit much from
-            a surrogate key, although a collection of composite values <emphasis>might</emphasis>.
-            It is for this reason that Hibernate provides a feature that allows you to map many-to-many
-            associations and collections of values to a table with a surrogate key.
-        </para>
+      <para>The majority of the many-to-many associations and collections of
+      values shown previously all map to tables with composite keys, even
+      though it has been have suggested that entities should have synthetic
+      identifiers (surrogate keys). A pure association table does not seem to
+      benefit much from a surrogate key, although a collection of composite
+      values <emphasis>might</emphasis>. It is for this reason Hibernate
+      provides a feature that allows you to map many-to-many associations and
+      collections of values to a table with a surrogate key.</para>
 
-        <para>
-            The <literal>&lt;idbag&gt;</literal> element lets you map a <literal>List</literal>
-            (or <literal>Collection</literal>) with bag semantics. For example:
-        </para>
+      <para>The <literal>&lt;idbag&gt;</literal> element lets you map a
+      <literal>List</literal> (or <literal>Collection</literal>) with bag
+      semantics. For example:</para>
 
-<programlisting role="XML"><![CDATA[<idbag name="lovers" table="LOVERS">
-    <collection-id column="ID" type="long">
-        <generator class="sequence"/>
-    </collection-id>
-    <key column="PERSON1"/>
-    <many-to-many column="PERSON2" class="Person" fetch="join"/>
-</idbag>]]></programlisting>
+      <programlisting role="XML">&lt;idbag name="lovers" table="LOVERS"&gt;
+    &lt;collection-id column="ID" type="long"&gt;
+        &lt;generator class="sequence"/&gt;
+    &lt;/collection-id&gt;
+    &lt;key column="PERSON1"/&gt;
+    &lt;many-to-many column="PERSON2" class="Person" fetch="join"/&gt;
+&lt;/idbag&gt;</programlisting>
 
-        <para>
-            An <literal>&lt;idbag&gt;</literal> has a synthetic id generator,
-            just like an entity class. A different surrogate key is assigned to each collection
-            row. Hibernate does not, however, provide any mechanism for discovering the surrogate key value
-            of a particular row.
-        </para>
+      <para>An <literal>&lt;idbag&gt;</literal> has a synthetic id generator,
+      just like an entity class. A different surrogate key is assigned to each
+      collection row. Hibernate does not, however, provide any mechanism for
+      discovering the surrogate key value of a particular row.</para>
 
-        <para>
-            The update performance of an <literal>&lt;idbag&gt;</literal> supersedes a regular <literal>&lt;bag&gt;</literal>.
-            Hibernate can locate individual rows efficiently and update or delete them
-            individually, similar to a list, map or set.
-        </para>
+      <para>The update performance of an <literal>&lt;idbag&gt;</literal>
+      supersedes a regular <literal>&lt;bag&gt;</literal>. Hibernate can
+      locate individual rows efficiently and update or delete them
+      individually, similar to a list, map or set.</para>
 
-        <para>
-            In the current implementation, the <literal>native</literal> identifier generation
-            strategy is not supported for <literal>&lt;idbag&gt;</literal> collection identifiers.
-        </para>
-
+      <para>In the current implementation, the <literal>native</literal>
+      identifier generation strategy is not supported for
+      <literal>&lt;idbag&gt;</literal> collection identifiers.</para>
     </section>
+  </section>
 
-    </section>
-    
-    <!--undocumenting this stuff -->
-    
-    <!--section id="collections-heterogeneous">
+  <!--undocumenting this stuff -->
+
+  <!--section id="collections-heterogeneous">
         <title>Heterogeneous Associations</title>
 
         <para>
@@ -1092,182 +1551,319 @@
 
     </section-->
 
-    <section id="collections-example" revision="1">
-        <title>Collection examples</title>
+  <section id="collections-example" revision="1">
+    <title>Collection examples</title>
 
-        <para>
-            This section covers collection examples. 
-	</para>
+    <para>This section covers collection examples.</para>
 
-	<para>
-	    The following class has a collection of <literal>Child</literal> instances:
-        </para>
+    <para>The following class has a collection of <literal>Child</literal>
+    instances:</para>
 
-        <programlisting role="JAVA"><![CDATA[package eg;
-import java.util.Set;
+    <example>
+      <title>Example classes <classname>Parent</classname> and
+      <classname>Child</classname></title>
 
-public class Parent {
+      <programlisting role="JAVA">public class Parent {
     private long id;
-    private Set children;
+    private Set&lt;Child&gt; children;
 
-    public long getId() { return id; }
-    private void setId(long id) { this.id=id; }
+    // getter/setter
+    ...
+}
 
-    private Set getChildren() { return children; }
-    private void setChildren(Set children) { this.children=children; }
 
-    ....
-    ....
-}]]></programlisting>
+public class Child {
+   private long id;
+   private String name
 
-        <para>
-            If each child has, at most, one parent, the most natural mapping is a 
-            one-to-many association:
-            
-        </para>
+   
+   // getter/setter
+   ...
+}</programlisting>
+    </example>
 
-        <programlisting role="XML"><![CDATA[<hibernate-mapping>
+    <para>If each child has, at most, one parent, the most natural mapping is
+    a one-to-many association:</para>
 
-    <class name="Parent">
-        <id name="id">
-            <generator class="sequence"/>
-        </id>
-        <set name="children">
-            <key column="parent_id"/>
-            <one-to-many class="Child"/>
-        </set>
-    </class>
+    <example>
+      <title>One to many unidirectional <classname>Parent-Child</classname>
+      relationship using annotations</title>
 
-    <class name="Child">
-        <id name="id">
-            <generator class="sequence"/>
-        </id>
-        <property name="name"/>
-    </class>
+      <programlisting role="XML">public class Parent {
+    @Id
+    @GeneratedValue
+    private long id;
 
-</hibernate-mapping>]]></programlisting>
+    @OneToMany
+    private Set&lt;Child&gt; children;
 
-        <para>
-            This maps to the following table definitions:
-        </para>
+    // getter/setter
+    ...
+}
 
-        <programlisting role="XML"><![CDATA[create table parent ( id bigint not null primary key )
+
+public class Child {
+   @Id
+   @GeneratedValue
+   private long id;
+   private String name;
+
+   
+   // getter/setter
+   ...
+}</programlisting>
+    </example>
+
+    <example>
+      <title>One to many unidirectional <classname>Parent-Child</classname>
+      relationship using mapping files</title>
+
+      <programlisting role="XML">&lt;hibernate-mapping&gt;
+
+    &lt;class name="Parent"&gt;
+        &lt;id name="id"&gt;
+            &lt;generator class="sequence"/&gt;
+        &lt;/id&gt;
+        &lt;set name="children"&gt;
+            &lt;key column="parent_id"/&gt;
+            &lt;one-to-many class="Child"/&gt;
+        &lt;/set&gt;
+    &lt;/class&gt;
+
+    &lt;class name="Child"&gt;
+        &lt;id name="id"&gt;
+            &lt;generator class="sequence"/&gt;
+        &lt;/id&gt;
+        &lt;property name="name"/&gt;
+    &lt;/class&gt;
+
+&lt;/hibernate-mapping&gt;</programlisting>
+    </example>
+
+    <para>This maps to the following table definitions:</para>
+
+    <example>
+      <title>Table definitions for unidirectional
+      <classname>Parent</classname>-<classname>Child</classname>
+      relationship</title>
+
+      <programlisting role="XML">create table parent ( id bigint not null primary key )
 create table child ( id bigint not null primary key, name varchar(255), parent_id bigint )
-alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+alter table child add constraint childfk0 (parent_id) references parent</programlisting>
+    </example>
 
-        <para>
-            If the parent is <emphasis>required</emphasis>, use a bidirectional one-to-many
-            association:
-        </para>
+    <para>If the parent is <emphasis>required</emphasis>, use a bidirectional
+    one-to-many association:</para>
 
-        <programlisting role="XML"><![CDATA[<hibernate-mapping>
+    <example>
+      <title>One to many bidirectional <classname>Parent-Child</classname>
+      relationship using annotations</title>
 
-    <class name="Parent">
-        <id name="id">
-            <generator class="sequence"/>
-        </id>
-        <set name="children" inverse="true">
-            <key column="parent_id"/>
-            <one-to-many class="Child"/>
-        </set>
-    </class>
+      <programlisting role="XML">public class Parent {
+    @Id
+    @GeneratedValue
+    private long id;
 
-    <class name="Child">
-        <id name="id">
-            <generator class="sequence"/>
-        </id>
-        <property name="name"/>
-        <many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/>
-    </class>
+    @OneToMany(mappedBy="parent")
+    private Set&lt;Child&gt; children;
 
-</hibernate-mapping>]]></programlisting>
+    // getter/setter
+    ...
+}
 
-        <para>
-            Notice the <literal>NOT NULL</literal> constraint:
-        </para>
 
-        <programlisting role="XML"><![CDATA[create table parent ( id bigint not null primary key )
+public class Child {
+   @Id
+   @GeneratedValue
+   private long id;
+
+   private String name;
+ 
+   @ManyToOne
+   private Parent parent;
+
+   
+   // getter/setter
+   ...
+}</programlisting>
+    </example>
+
+    <example>
+      <title>One to many bidirectional <classname>Parent-Child</classname>
+      relationship using mapping files</title>
+
+      <programlisting role="XML">&lt;hibernate-mapping&gt;
+
+    &lt;class name="Parent"&gt;
+        &lt;id name="id"&gt;
+            &lt;generator class="sequence"/&gt;
+        &lt;/id&gt;
+        &lt;set name="children" inverse="true"&gt;
+            &lt;key column="parent_id"/&gt;
+            &lt;one-to-many class="Child"/&gt;
+        &lt;/set&gt;
+    &lt;/class&gt;
+
+    &lt;class name="Child"&gt;
+        &lt;id name="id"&gt;
+            &lt;generator class="sequence"/&gt;
+        &lt;/id&gt;
+        &lt;property name="name"/&gt;
+        &lt;many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/&gt;
+    &lt;/class&gt;
+
+&lt;/hibernate-mapping&gt;</programlisting>
+    </example>
+
+    <para>Notice the <literal>NOT NULL</literal> constraint:</para>
+
+    <example>
+      <title>Table definitions for bidirectional
+      <classname>Parent</classname>-<classname>Child</classname>
+      relationship</title>
+
+      <programlisting role="XML">create table parent ( id bigint not null primary key )
 create table child ( id bigint not null
                      primary key,
                      name varchar(255),
                      parent_id bigint not null )
-alter table child add constraint childfk0 (parent_id) references parent]]></programlisting>
+alter table child add constraint childfk0 (parent_id) references parent</programlisting>
+    </example>
 
-        <para>
-            Alternatively, if this association must be unidirectional
-            you can declare the <literal>NOT NULL</literal> constraint on the <literal>&lt;key&gt;</literal>
-            mapping:
-        </para>
+    <para>Alternatively, if this association must be unidirectional you can
+    enforce the <literal>NOT NULL</literal> constraint.</para>
 
-        <programlisting role="XML"><![CDATA[<hibernate-mapping>
+    <example>
+      <title>Enforcing NOT NULL constraint in unidirectional relation using
+      annotations</title>
 
-    <class name="Parent">
-        <id name="id">
-            <generator class="sequence"/>
-        </id>
-        <set name="children">
-            <key column="parent_id" not-null="true"/>
-            <one-to-many class="Child"/>
-        </set>
-    </class>
+      <programlisting role="XML">public class Parent {
+    @Id
+    @GeneratedValue
+    private long id;
 
-    <class name="Child">
-        <id name="id">
-            <generator class="sequence"/>
-        </id>
-        <property name="name"/>
-    </class>
+    @OneToMany(optional=false)
+    private Set&lt;Child&gt; children;
 
-</hibernate-mapping>]]></programlisting>
+    // getter/setter
+    ...
+}
 
-        <para>
-            On the other hand, if a child has multiple parents, a many-to-many
-            association is appropriate:
-        </para>
 
-        <programlisting role="XML"><![CDATA[<hibernate-mapping>
+public class Child {
+   @Id
+   @GeneratedValue
+   private long id;
+   private String name;
 
-    <class name="Parent">
-        <id name="id">
-            <generator class="sequence"/>
-        </id>
-        <set name="children" table="childset">
-            <key column="parent_id"/>
-            <many-to-many class="Child" column="child_id"/>
-        </set>
-    </class>
+   
+   // getter/setter
+   ...
+}</programlisting>
+    </example>
 
-    <class name="Child">
-        <id name="id">
-            <generator class="sequence"/>
-        </id>
-        <property name="name"/>
-    </class>
+    <example>
+      <title>Enforcing NOT NULL constraint in unidirectional relation using
+      mapping files</title>
 
-</hibernate-mapping>]]></programlisting>
+      <programlisting role="XML">&lt;hibernate-mapping&gt;
 
-        <para>
-            Table definitions:
-        </para>
+    &lt;class name="Parent"&gt;
+        &lt;id name="id"&gt;
+            &lt;generator class="sequence"/&gt;
+        &lt;/id&gt;
+        &lt;set name="children"&gt;
+            &lt;key column="parent_id" not-null="true"/&gt;
+            &lt;one-to-many class="Child"/&gt;
+        &lt;/set&gt;
+    &lt;/class&gt;
 
-        <programlisting><![CDATA[create table parent ( id bigint not null primary key )
+    &lt;class name="Child"&gt;
+        &lt;id name="id"&gt;
+            &lt;generator class="sequence"/&gt;
+        &lt;/id&gt;
+        &lt;property name="name"/&gt;
+    &lt;/class&gt;
+
+&lt;/hibernate-mapping&gt;</programlisting>
+    </example>
+
+    <para>On the other hand, if a child has multiple parents, a many-to-many
+    association is appropriate.</para>
+
+    <example>
+      <title>Many to many <classname>Parent-Child</classname> relationship
+      using annotations</title>
+
+      <programlisting role="XML">public class Parent {
+    @Id
+    @GeneratedValue
+    private long id;
+
+    @ManyToMany
+    private Set&lt;Child&gt; children;
+
+    // getter/setter
+    ...
+}
+
+
+public class Child {
+   @Id
+   @GeneratedValue
+   private long id;
+
+   private String name;
+
+   
+   // getter/setter
+   ...
+}</programlisting>
+    </example>
+
+    <example>
+      <title>Many to many <classname>Parent-Child</classname> relationship
+      using mapping files</title>
+
+      <programlisting role="XML">&lt;hibernate-mapping&gt;
+
+    &lt;class name="Parent"&gt;
+        &lt;id name="id"&gt;
+            &lt;generator class="sequence"/&gt;
+        &lt;/id&gt;
+        &lt;set name="children" table="childset"&gt;
+            &lt;key column="parent_id"/&gt;
+            &lt;many-to-many class="Child" column="child_id"/&gt;
+        &lt;/set&gt;
+    &lt;/class&gt;
+
+    &lt;class name="Child"&gt;
+        &lt;id name="id"&gt;
+            &lt;generator class="sequence"/&gt;
+        &lt;/id&gt;
+        &lt;property name="name"/&gt;
+    &lt;/class&gt;
+
+&lt;/hibernate-mapping&gt;</programlisting>
+    </example>
+
+    <para>Table definitions:</para>
+
+    <example>
+      <title>Table definitions for many to many releationship</title>
+
+      <programlisting>create table parent ( id bigint not null primary key )
 create table child ( id bigint not null primary key, name varchar(255) )
 create table childset ( parent_id bigint not null,
                         child_id bigint not null,
                         primary key ( parent_id, child_id ) )
 alter table childset add constraint childsetfk0 (parent_id) references parent
-alter table childset add constraint childsetfk1 (child_id) references child]]></programlisting>
+alter table childset add constraint childsetfk1 (child_id) references child</programlisting>
+    </example>
 
-        <para>
-            For more examples and a complete explanation of a parent/child relationship mapping,
-            see <xref linkend="example-parentchild"/> for more information.
-        </para>
-        
-        <para>
-            Even more complex association mappings are covered
-            in the next chapter.
-        </para>
-
-    </section>
-
+    <para>For more examples and a complete explanation of a parent/child
+    relationship mapping, see <xref linkend="example-parentchild" /> for more
+    information. Even more complex association mappings are covered in the
+    next chapter.</para>
+  </section>
 </chapter>



More information about the hibernate-commits mailing list