alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Hibernate example source code file (association_mapping.xml)

This example Hibernate source code file (association_mapping.xml) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Hibernate tags/keywords

a, address, address, cdata, cdata, hibernate, person, person, personaddress, public, the, this, xml, xml

The Hibernate association_mapping.xml source code

<?xml version='1.0' encoding="UTF-8"?>
<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
  ~ indicated by the @author tags or express copyright attribution
  ~ statements applied by the authors.  All third-party contributions are
  ~ distributed under license by Red Hat Middleware LLC.
  ~
  ~ This copyrighted material is made available to anyone wishing to use, modify,
  ~ copy, or redistribute it subject to the terms and conditions of the GNU
  ~ Lesser General Public License, as published by the Free Software Foundation.
  ~
  ~ This program is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  ~ for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public License
  ~ along with this distribution; if not, write to:
  ~ Free Software Foundation, Inc.
  ~ 51 Franklin Street, Fifth Floor
  ~ Boston, MA  02110-1301  USA
  -->

<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
<!ENTITY % BOOK_ENTITIES SYSTEM "../HIBERNATE_-_Relational_Persistence_for_Idiomatic_Java.ent">
%BOOK_ENTITIES;

]>

<chapter id="associations">

    <title>Association Mappings

    <section id="assoc-intro" revision="1">
        <title>Introduction
        
        <para>
            Association mappings are often the most difficult thing to implement correctly. In
            this section we examine some canonical cases one by one, starting
            with unidirectional mappings and then bidirectional cases.
            We will use <literal>Person and Address in all
            the examples.
        </para>
        
        <para>
        	Associations will be classified by multiplicity and whether or not they map to an intervening
        	join table.
        </para>
        
        <para>
        	Nullable foreign keys are not considered to be good practice in traditional data
        	modelling, so our examples do not use nullable foreign keys. This is not a
        	requirement of Hibernate, and the mappings will work if you drop the
        	nullability constraints.
        </para>
        
    </section>

    <section id="assoc-unidirectional" revision="1">
        <title>Unidirectional associations
        
        <section id="assoc-unidirectional-m21">
        <title>Many-to-one
        
        <para>
            A <emphasis>unidirectional many-to-one association is the most 
            common kind of unidirectional association.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <many-to-one name="address" 
        column="addressId"
        not-null="true"/>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>]]>
        <programlisting>
        
        </section>

        <section id="assoc-unidirectional-121">
        <title>One-to-one
        
        <para>
            A <emphasis>unidirectional one-to-one association on a foreign key
            is almost identical. The only difference is the column unique constraint.
        </para>
        
       <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <many-to-one name="address" 
        column="addressId" 
        unique="true"
        not-null="true"/>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>]]>
        <programlisting>
        
        <para>
            A <emphasis>unidirectional one-to-one association on a primary key
            usually uses a special id generator In this example, however, we have reversed the direction
            of the association:
        </para>
        
       <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
</class>

<class name="Address">
    <id name="id" column="personId">
        <generator class="foreign">
            <param name="property">person
        </generator>
    </id>
    <one-to-one name="person" constrained="true"/>
</class>]]>
        <programlisting>
        
        </section>
        
        <section id="assoc-unidirectional-12m">
        <title>One-to-many
        
        <para>
            A <emphasis>unidirectional one-to-many association on a foreign key 
            is an unusual case, and is not recommended.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses">
        <key column="personId" 
            not-null="true"/>
        <one-to-many class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>]]>
        <programlisting>
        
        <para>
          You should instead use a join table for this kind of association.
        </para>
        
        </section>
    
    </section>

    <section id="assoc-unidirectional-join" revision="1">
        <title>Unidirectional associations with join tables
        
        <section id="assoc-unidirectional-join-12m">
        <title>One-to-many
        
        <para>
            A <emphasis>unidirectional one-to-many association on a join table 
            is the preferred option. Specifying <literal>unique="true",
            changes the multiplicity from many-to-many to one-to-many.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses" table="PersonAddress">
        <key column="personId"/>
        <many-to-many column="addressId"
            unique="true"
            class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>]]>
        <programlisting>
        
        </section>

        <section id="assoc-unidirectional-join-m21">
        <title>Many-to-one
        
        <para>
            A <emphasis>unidirectional many-to-one association on a join table 
            is common when the association is optional. For example:
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <join table="PersonAddress" 
        optional="true">
        <key column="personId" unique="true"/>
        <many-to-one name="address"
            column="addressId" 
            not-null="true"/>
    </join>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>]]>
        <programlisting>
        
        </section>

        <section id="assoc-unidirectional-join-121">
        <title>One-to-one
        
        <para>
            A <emphasis>unidirectional one-to-one association on a join table is possible, 
   	but extremely unusual.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <join table="PersonAddress" 
        optional="true">
        <key column="personId" 
            unique="true"/>
        <many-to-one name="address"
            column="addressId" 
            not-null="true"
            unique="true"/>
    </join>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>]]>
        <programlisting>
        
        </section>

        <section id="assoc-unidirectional-join-m2m">
        <title>Many-to-many
        
        <para>
            Finally, here is an example of a <emphasis>unidirectional many-to-many association.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses" table="PersonAddress">
        <key column="personId"/>
        <many-to-many column="addressId"
            class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
</class>]]>
        <programlisting>
        
        </section>

    </section>

    <section id="assoc-bidirectional" revision="1">
        <title>Bidirectional associations
        
        <section id="assoc-bidirectional-m21" revision="2">
        <title>one-to-many / many-to-one
        
        <para>
            A <emphasis>bidirectional many-to-one association is the
            most common kind of association. The following example illustrates the standard parent/child
            relationship.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <many-to-one name="address" 
        column="addressId"
        not-null="true"/>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
    <set name="people" inverse="true">
        <key column="addressId"/>
        <one-to-many class="Person"/>
    </set>
</class>]]>

        <programlisting>

        <para>
            If you use a <literal>List, or other indexed collection,
            set the <literal>key column of the foreign key to not null.
            Hibernate will manage the association from the collections side to maintain the index
            of each element, making the other side virtually inverse by setting
            <literal>update="false" and insert="false":
        </para>

        <programlisting role="XML">
   <id name="id"/>
   ...
   <many-to-one name="address"
      column="addressId"
      not-null="true"
      insert="false"
      update="false"/>
</class>

<class name="Address">
   <id name="id"/>
   ...
   <list name="people">
      <key column="addressId" not-null="true"/>
      <list-index column="peopleIdx"/>
      <one-to-many class="Person"/>
   </list>
</class>]]>

            <para>
                If the underlying foreign key column is <literal>NOT NULL, it 
		is important that you define <literal>not-null="true" on the
                <literal><key> element of the collection mapping.
                Do not only
                declare <literal>not-null="true" on a possible nested
                <literal><column> element, but on the <key>
                element.
            </para>

        </section>
        
        <section id="assoc-bidirectional-121">
        <title>One-to-one
        
        <para>
            A <emphasis>bidirectional one-to-one association on a foreign key
            is common:
        </para>
        
       <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <many-to-one name="address" 
        column="addressId" 
        unique="true"
        not-null="true"/>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
   <one-to-one name="person" 
        property-ref="address"/>
</class>]]>
        <programlisting>
        
        <para>
            A <emphasis>bidirectional one-to-one association on a primary key
            uses the special id generator:
        </para>
        
       <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <one-to-one name="address"/>
</class>

<class name="Address">
    <id name="id" column="personId">
        <generator class="foreign">
            <param name="property">person
        </generator>
    </id>
    <one-to-one name="person" 
        constrained="true"/>
</class>]]>
        <programlisting>
        
        </section>
        
    </section>

    <section id="assoc-bidirectional-join" revision="1">
        <title>Bidirectional associations with join tables
        
        <section id="assoc-bidirectional-join-12m">
        <title>one-to-many / many-to-one
        
        <para>
            The following is an example of a <emphasis>bidirectional one-to-many association on a join table.
            The <literal>inverse="true" can go on either end of the
            association, on the collection, or on the join.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses" 
        table="PersonAddress">
        <key column="personId"/>
        <many-to-many column="addressId"
            unique="true"
            class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
    <join table="PersonAddress" 
        inverse="true" 
        optional="true">
        <key column="addressId"/>
        <many-to-one name="person"
            column="personId"
            not-null="true"/>
    </join>
</class>]]>
        <programlisting>
        
        </section>

         <section id="assoc-bidirectional-join-121">
        <title>one to one
        
        <para>
            A <emphasis>bidirectional one-to-one association on a join table is possible,
            but extremely unusual.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <join table="PersonAddress" 
        optional="true">
        <key column="personId" 
            unique="true"/>
        <many-to-one name="address"
            column="addressId" 
            not-null="true"
            unique="true"/>
    </join>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
    <join table="PersonAddress" 
        optional="true"
        inverse="true">
        <key column="addressId" 
            unique="true"/>
        <many-to-one name="person"
            column="personId" 
            not-null="true"
            unique="true"/>
    </join>
</class>]]>
        <programlisting>

        </section>
        
        <section id="assoc-bidirectional-join-m2m" revision="1">
        <title>Many-to-many
        
        <para>
            Here is an example of a <emphasis>bidirectional many-to-many association.
        </para>
        
        <programlisting role="XML">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses" table="PersonAddress">
        <key column="personId"/>
        <many-to-many column="addressId"
            class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
    <set name="people" inverse="true" table="PersonAddress">
        <key column="addressId"/>
        <many-to-many column="personId"
            class="Person"/>
    </set>
</class>]]>

        <programlisting>
        
        </section>
        
    </section>
    
    <section id="assoc-complex">
        <title>More complex association mappings
        
        <para>
            More complex association joins are <emphasis>extremely rare. 
            Hibernate handles more complex situations by using
            SQL fragments embedded in the mapping document. For example, if a table
            with historical account information data defines 
            <literal>accountNumber, effectiveEndDate 
            and <literal>effectiveStartDatecolumns, it would be mapped as follows:
        </para>
        
        <programlisting role="XML">
    <property name="accountNumber" type="string" not-null="true"/>
    <property name="currentAccount" type="boolean">
        <formula>case when effectiveEndDate is null then 1 else 0 end
    </property>
</properties>
<property name="effectiveEndDate" type="date"/>
<property name="effectiveStateDate" type="date" not-null="true"/>]]>

        <para>
            You can then map an association to the <emphasis>current instance, 
            the one with null <literal>effectiveEndDate, by using:
        </para>
        
        <programlisting role="XML">
</many-to-one>]]>

        <para>
            In a more complex example, imagine that the association between 
            <literal>Employee and Organization is maintained
            in an <literal>Employment table full of historical employment data.
            An association to the employee's <emphasis>most recent employer,
            the one with the most recent <literal>startDate, could be mapped in the following way:
        </para>
        
        <programlisting role="XML">
    <key column="employeeId"/>
    <subselect>
        select employeeId, orgId 
        from Employments 
        group by orgId 
        having startDate = max(startDate)
    </subselect>
    <many-to-one name="mostRecentEmployer" 
            class="Organization" 
            column="orgId"/>
</join>]]>

        <para>
            This functionality allows a degree of creativity and flexibility, but it is more practical 
            to handle these kinds of cases using HQL or a criteria query.
        </para>

    </section>

</chapter>

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate association_mapping.xml source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.