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

Hibernate example source code file (basic_mapping.xml)

This example Hibernate source code file (basic_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

entity, hibernate, hibernate, id, it, java, java, sql, string, string, the, this, xml, xml

The Hibernate basic_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="mapping">
  <title>Basic O/R Mapping

  <section id="mapping-declaration" revision="2">
    <title>Mapping declaration

    <para>Object/relational mappings can be defined in three
    approaches:</para>

    <itemizedlist>
      <listitem>
        <para>using Java 5 annotations (via the Java Persistence 2
        annotations)</para>
      </listitem>

      <listitem>
        <para>using JPA 2 XML deployment descriptors (described in chapter
        XXX)</para>
      </listitem>

      <listitem>
        <para>using the Hibernate legacy XML files approach known as
        hbm.xml</para>
      </listitem>
    </itemizedlist>

    <para>Annotations are split in two categories, the logical mapping
    annotations (describing the object model, the association between two
    entities etc.) and the physical mapping annotations (describing the
    physical schema, tables, columns, indexes, etc). We will mix annotations
    from both categories in the following code examples.</para>

    <para>JPA annotations are in the javax.persistence.*
    package. Hibernate specific extensions are in
    <literal>org.hibernate.annotations.*. You favorite IDE can
    auto-complete annotations and their attributes for you (even without a
    specific "JPA" plugin, since JPA annotations are plain Java 5
    annotations).</para>

    <para>Here is an example of mapping

    <programlisting role="JAVA">package eg;

@Entity 
@Table(name="cats") @Inheritance(strategy=SINGLE_TABLE)
@DiscriminatorValue("C") @DiscriminatorColumn(name="subclass", discriminatorType=CHAR)
public class Cat {
   
   @Id @GeneratedValue
   public Integer getId() { return id; }
   public void setId(Integer id) { this.id = id; }
   private Integer id;

   public BigDecimal getWeight() { return weight; }
   public void setWeight(BigDecimal weight) { this.weight = weight; }
   private BigDecimal weight;

   @Temporal(DATE) @NotNull @Column(updatable=false)
   public Date getBirthdate() { return birthdate; }
   public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
   private Date birthdate;

   @org.hibernate.annotations.Type(type="eg.types.ColorUserType")
   @NotNull @Column(updatable=false)
   public ColorType getColor() { return color; }
   public void setColor(ColorType color) { this.color = color; }
   private ColorType color;

   @NotNull @Column(updatable=false)
   public String getSex() { return sex; }
   public void setSex(String sex) { this.sex = sex; }
   private String sex;

   @NotNull @Column(updatable=false)
   public Integer getLitterId() { return litterId; }
   public void setLitterId(Integer litterId) { this.litterId = litterId; }
   private Integer litterId;

   @ManyToOne @JoinColumn(name="mother_id", updatable=false)
   public Cat getMother() { return mother; }
   public void setMother(Cat mother) { this.mother = mother; }
   private Cat mother;

   @OneToMany(mappedBy="mother") @OrderBy("litterId")
   public Set<Cat> getKittens() { return kittens; }
   public void setKittens(Set<Cat> kittens) { this.kittens = kittens; }
   private Set<Cat> kittens = new HashSet<Cat>();
}

@Entity @DiscriminatorValue("D")
public class DomesticCat extends Cat {

   public String getName() { return name; }
   public void setName(String name) { this.name = name }
   private String name;
}

@Entity
public class Dog { ... }</programlisting>

    <para>The legacy hbm.xml approach uses an XML schema designed to be
    readable and hand-editable. The mapping language is Java-centric, meaning
    that mappings are constructed around persistent class declarations and not
    table declarations.</para>

    <para>Please note that even though many Hibernate users choose to write
    the XML by hand, a number of tools exist to generate the mapping document.
    These include XDoclet, Middlegen and AndroMDA.</para>

    <para>Here is an example mapping:

    <programlisting role="XML"><?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="eg">

        <class name="Cat"
            table="cats"
            discriminator-value="C">

                <id name="id">
                        <generator class="native"/>
                </id>

                <discriminator column="subclass"
                     type="character"/>

                <property name="weight"/>

                <property name="birthdate"
                    type="date"
                    not-null="true"
                    update="false"/>

                <property name="color"
                    type="eg.types.ColorUserType"
                    not-null="true"
                    update="false"/>

                <property name="sex"
                    not-null="true"
                    update="false"/>

                <property name="litterId"
                    column="litterId"
                    update="false"/>

                <many-to-one name="mother"
                    column="mother_id"
                    update="false"/>

                <set name="kittens"
                    inverse="true"
                    order-by="litter_id">
                        <key column="mother_id"/>
                        <one-to-many class="Cat"/>
                </set>

                <subclass name="DomesticCat"
                    discriminator-value="D">

                        <property name="name"
                            type="string"/>

                </subclass>

        </class>

        <class name="Dog">
                <!-- mapping for Dog could go here -->
        </class>

</hibernate-mapping></programlisting>

    <para>We will now discuss the concepts of the mapping documents (both
    annotations and XML). We will only describe, however, the document
    elements and attributes that are used by Hibernate at runtime. The mapping
    document also contains some extra optional attributes and elements that
    affect the database schemas exported by the schema export tool (for
    example, the <literal> not-null attribute).

    <section id="mapping-declaration-class" revision="4">
      <title>Entity

      <para>An entity is a regular Java object (aka POJO) which will be
      persisted by Hibernate.</para>

      <para>To mark an object as an entity in annotations, use the
      <classname>@Entity annotation.

      <programlisting language="JAVA" role="JAVA">@Entity
public class Flight implements Serializable {
    Long id;

    @Id
    public Long getId() { return id; }

    public void setId(Long id) { this.id = id; }
}         </programlisting>

      <para>That's pretty much it, the rest is optional. There are however any
      options to tweak your entity mapping, let's explore them.</para>

      <para>@Table lets you define the table the entity
      will be persisted into. If undefined, the table name is the unqualified
      class name of the entity. You can also optionally define the catalog,
      the schema as well as unique constraints on the table.</para>

      <programlisting role="JAVA">@Entity
@Table(name="TBL_FLIGHT", 
       schema="AIR_COMMAND", 
       uniqueConstraints=
           @UniqueConstraint(
               name="flight_number", 
               columnNames={"comp_prefix", "flight_number"} ) )
public class Flight implements Serializable {
    @Column(name="comp_prefix")
    public String getCompagnyPrefix() { return companyPrefix; }

    @Column(name="flight_number")
    public String getNumber() { return number; }
}</programlisting>

      <para>The constraint name is optional (generated if left undefined). The
      column names composing the constraint correspond to the column names as
      defined before the Hibernate <classname>NamingStrategy is
      applied.</para>

      <tip>
        <para>Be sure to use the database-level column names for the columnNames
         property of a <literal>@UniqueConstraint. For example, whilst for simple types the
         database-level column name may be the same as the entity-level property name, this is often
         not the case for relational properties.
        </para>
      </tip>

      <para>@Entity.name lets you define the shortcut name
      of the entity you can used in JP-QL and HQL queries. It defaults to the
      unqualified class name of the class.</para>

      <para>Hibernate goes beyond the JPA specification and provide additional
      configurations. Some of them are hosted on
      <classname>@org.hibernate.annotations.Entity:

      <itemizedlist>
        <listitem>
          <para>dynamicInsert /
          <literal>dynamicUpdate (defaults to false): specifies that
          <literal>INSERT / UPDATE SQL should be
          generated at runtime and contain only the columns whose values are
          not null. The <literal>dynamic-update and
          <literal>dynamic-insert settings are not inherited by
          subclasses. Although these settings can increase performance in some
          cases, they can actually decrease performance in others.</para>
        </listitem>

        <listitem>
          <para>selectBeforeUpdate (defaults to false):
          specifies that Hibernate should <emphasis>never perform
          an SQL <literal>UPDATE unless it is certain that an object
          is actually modified. Only when a transient object has been
          associated with a new session using <literal>update(),
          will Hibernate perform an extra SQL <literal>SELECT to
          determine if an <literal>UPDATE is actually required. Use
          of <literal>select-before-update will usually decrease
          performance. It is useful to prevent a database update trigger being
          called unnecessarily if you reattach a graph of detached instances
          to a <literal>Session.
        </listitem>

        <listitem>
          <para>polymorphisms (defaults to
          <literal>IMPLICIT): determines whether implicit or
          explicit query polymorphisms is used. <emphasis>Implicit
          polymorphisms means that instances of the class will be returned by
          a query that names any superclass or implemented interface or class,
          and that instances of any subclass of the class will be returned by
          a query that names the class itself. <emphasis>Explicit
          polymorphisms means that class instances will be returned only by
          queries that explicitly name that class. Queries that name the class
          will return only instances of subclasses mapped. For most purposes,
          the default <literal>polymorphisms=IMPLICIT is
          appropriate. Explicit polymorphisms is useful when two different
          classes are mapped to the same table This allows a "lightweight"
          class that contains a subset of the table columns.</para>
        </listitem>

        <listitem>
          <para>persister: specifies a custom
          <literal>ClassPersister. The persister
          attribute lets you customize the persistence strategy used for the
          class. You can, for example, specify your own subclass of
          <literal>org.hibernate.persister.EntityPersister, or you
          can even provide a completely new implementation of the interface
          <literal>org.hibernate.persister.ClassPersister that
          implements, for example, persistence via stored procedure calls,
          serialization to flat files or LDAP. See
          <literal>org.hibernate.test.CustomPersister for a simple
          example of "persistence" to a <literal>Hashtable.
        </listitem>

        <listitem>
          <para>optimisticLock (defaults to
          <literal>VERSION): determines the optimistic locking
          strategy. If you enable <literal>dynamicUpdate, you will
          have a choice of optimistic locking strategies:</para>

          <itemizedlist>
            <listitem>
              <para>version: check the version/timestamp
              columns</para>
            </listitem>

            <listitem>
              <para>all: check all columns
            </listitem>

            <listitem>
              <para>dirty: check the changed columns,
              allowing some concurrent updates</para>
            </listitem>

            <listitem>
              <para>none: do not use optimistic
              locking</para>
            </listitem>
          </itemizedlist>

          <para>It is strongly recommended that you use
          version/timestamp columns for optimistic locking with Hibernate.
          This strategy optimizes performance and correctly handles
          modifications made to detached instances (i.e. when
          <literal>Session.merge() is used).
        </listitem>
      </itemizedlist>

      <tip>
        <para>Be sure to import
        <classname>@javax.persistence.Entity to mark a class as an
        entity. It's a common mistake to import
        <classname>@org.hibernate.annotations.Entity by
        accident.</para>
      </tip>

      <para>Some entities are not mutable. They cannot be updated or deleted
      by the application. This allows Hibernate to make some minor performance
      optimizations.. Use the <classname>@Immutable
      annotation.</para>

      <para>You can also alter how Hibernate deals with lazy initialization
      for this class. On <classname>@Proxy, use
      <literal>lazy=false to disable lazy fetching (not
      recommended). You can also specify an interface to use for lazy
      initializing proxies (defaults to the class itself): use
      <literal>proxyClass on @Proxy.
      Hibernate will initially return proxies (Javassist or CGLIB) that
      implement the named interface. The persistent object will load when a
      method of the proxy is invoked. See "Initializing collections and
      proxies" below.</para>

      <para>@BatchSize specifies a "batch size" for
      fetching instances of this class by identifier. Not yet loaded instances
      are loaded batch-size at a time (default 1).</para>

      <para>You can specific an arbitrary SQL WHERE condition to be used when
      retrieving objects of this class. Use <classname>@Where for
      that.</para>

      <para>In the same vein, @Check lets you define an
      SQL expression used to generate a multi-row <emphasis>check
      constraint for automatic schema generation.</para>

      <para>There is no difference between a view and a base table for a
      Hibernate mapping. This is transparent at the database level, although
      some DBMS do not support views properly, especially with updates.
      Sometimes you want to use a view, but you cannot create one in the
      database (i.e. with a legacy schema). In this case, you can map an
      immutable and read-only entity to a given SQL subselect expression using
      <classname>@org.hibernate.annotations.Subselect:

      <programlisting role="JAVA">@Entity
@Subselect("select item.name, max(bid.amount), count(*) "
        + "from item "
        + "join bid on bid.item_id = item.id "
        + "group by item.name")
@Synchronize( {"item", "bid"} ) //tables impacted
public class Summary {
    @Id
    public String getId() { return id; }
    ...
}</programlisting>

      <para>Declare the tables to synchronize this entity with, ensuring that
      auto-flush happens correctly and that queries against the derived entity
      do not return stale data. The <literal><subselect> is
      available both as an attribute and a nested mapping element.</para>

      <para>We will now explore the same options using the hbm.xml structure.
      You can declare a persistent class using the <literal>class
      element. For example:</para>

      <programlistingco role="XML">
        <areaspec>
          <area coords="2" id="class1" />

          <area coords="3" id="class2" />

          <area coords="4" id="class3" />

          <area coords="5" id="class4" />

          <area coords="6" id="class5" />

          <area coords="7" id="class6" />

          <area coords="8" id="class7" />

          <area coords="9" id="class8" />

          <area coords="10" id="class9" />

          <area coords="11" id="class10" />

          <area coords="12" id="class11" />

          <area coords="13" id="class12" />

          <area coords="14" id="class13" />

          <area coords="15" id="class14" />

          <area coords="16" id="class15" />

          <area coords="17" id="class16" />

          <area coords="18" id="class17" />

          <area coords="19" id="class18" />

          <area coords="20" id="class19" />

          <area coords="21" id="class20" />

          <area coords="22" id="class21" />
        </areaspec>

        <programlisting><class
        name="ClassName"
        table="tableName"
        discriminator-value="discriminator_value"
        mutable="true|false"
        schema="owner"
        catalog="catalog"
        proxy="ProxyInterface"
        dynamic-update="true|false"
        dynamic-insert="true|false"
        select-before-update="true|false"
        polymorphism="implicit|explicit"
        where="arbitrary sql where condition"
        persister="PersisterClass"
        batch-size="N"
        optimistic-lock="none|version|dirty|all"
        lazy="true|false"
        entity-name="EntityName"
        check="arbitrary sql check condition"
        rowid="rowid"
        subselect="SQL expression"
        abstract="true|false"
        node="element-name"
/></programlisting>

        <calloutlist>
          <callout arearefs="class1">
            <para>name (optional): the fully qualified Java
            class name of the persistent class or interface. If this attribute
            is missing, it is assumed that the mapping is for a non-POJO
            entity.</para>
          </callout>

          <callout arearefs="class2">
            <para>table (optional - defaults to the
            unqualified class name): the name of its database table.</para>
          </callout>

          <callout arearefs="class3">
            <para>discriminator-value (optional - defaults
            to the class name): a value that distinguishes individual
            subclasses that is used for polymorphic behavior. Acceptable
            values include <literal>null and not
            null</literal>.
          </callout>

          <callout arearefs="class4">
            <para>mutable (optional - defaults to
            <literal>true): specifies that instances of the class
            are (not) mutable.</para>
          </callout>

          <callout arearefs="class5">
            <para>schema (optional): overrides the schema
            name specified by the root
            <literal><hibernate-mapping> element.
          </callout>

          <callout arearefs="class6">
            <para>catalog (optional): overrides the catalog
            name specified by the root
            <literal><hibernate-mapping> element.
          </callout>

          <callout arearefs="class7">
            <para>proxy (optional): specifies an interface
            to use for lazy initializing proxies. You can specify the name of
            the class itself.</para>
          </callout>

          <callout arearefs="class8">
            <para>dynamic-update (optional - defaults to
            <literal>false): specifies that
            <literal>UPDATE SQL should be generated at runtime and
            can contain only those columns whose values have changed.</para>
          </callout>

          <callout arearefs="class9">
            <para>dynamic-insert (optional - defaults to
            <literal>false): specifies that
            <literal>INSERT SQL should be generated at runtime and
            contain only the columns whose values are not null.</para>
          </callout>

          <callout arearefs="class10">
            <para>select-before-update (optional - defaults
            to <literal>false): specifies that Hibernate should
            <emphasis>never perform an SQL
            <literal>UPDATE unless it is certain that an object is
            actually modified. Only when a transient object has been
            associated with a new session using <literal>update(),
            will Hibernate perform an extra SQL <literal>SELECT to
            determine if an <literal>UPDATE is actually
            required.</para>
          </callout>

          <callout arearefs="class11">
            <para>polymorphisms (optional - defaults to
            <literal>implicit): determines whether implicit or
            explicit query polymorphisms is used.</para>
          </callout>

          <callout arearefs="class12">
            <para>where (optional): specifies an arbitrary
            SQL <literal>WHERE condition to be used when retrieving
            objects of this class.</para>
          </callout>

          <callout arearefs="class13">
            <para>persister (optional): specifies a custom
            <literal>ClassPersister.
          </callout>

          <callout arearefs="class14">
            <para>batch-size (optional - defaults to
            <literal>1): specifies a "batch size" for fetching
            instances of this class by identifier.</para>
          </callout>

          <callout arearefs="class15">
            <para>optimistic-lock (optional - defaults to
            <literal>version): determines the optimistic locking
            strategy.</para>
          </callout>

          <callout arearefs="class16">
            <para>lazy (optional): lazy fetching can be
            disabled by setting <literal>lazy="false".
          </callout>

          <callout arearefs="class17">
            <para>entity-name (optional - defaults to the
            class name): Hibernate3 allows a class to be mapped multiple
            times, potentially to different tables. It also allows entity
            mappings that are represented by Maps or XML at the Java level. In
            these cases, you should provide an explicit arbitrary name for the
            entity. See <xref linkend="persistent-classes-dynamicmodels" />
            and <xref linkend="xml" /> for more information.
          </callout>

          <callout arearefs="class18">
            <para>check (optional): an SQL expression used
            to generate a multi-row <emphasis>check constraint for
            automatic schema generation.</para>
          </callout>

          <callout arearefs="class19">
            <para>rowid (optional): Hibernate can use
            ROWIDs on databases. On Oracle, for example, Hibernate can use the
            <literal>rowid extra column for fast updates once this
            option has been set to <literal>rowid. A ROWID is an
            implementation detail and represents the physical location of a
            stored tuple.</para>
          </callout>

          <callout arearefs="class20">
            <para>subselect (optional): maps an immutable
            and read-only entity to a database subselect. This is useful if
            you want to have a view instead of a base table. See below for
            more information.</para>
          </callout>

          <callout arearefs="class21">
            <para>abstract (optional): is used to mark
            abstract superclasses in <literal><union-subclass>
            hierarchies.</para>
          </callout>
        </calloutlist>
      </programlistingco>

      <para>It is acceptable for the named persistent class to be an
      interface. You can declare implementing classes of that interface using
      the <literal><subclass> element. You can persist any
      <emphasis>static inner class. Specify the class name using
      the standard form i.e. <literal>e.g.Foo$Bar.

      <para>Here is how to do a virtual view (subselect) in XML:

      <programlisting role="XML"><class name="Summary">
    <subselect>
        select item.name, max(bid.amount), count(*)
        from item
        join bid on bid.item_id = item.id
        group by item.name
    </subselect>
    <synchronize table="item"/>
    <synchronize table="bid"/>
    <id name="name"/>
    ...
</class></programlisting>

      <para>The <subselect> is available both as an
      attribute and a nested mapping element.</para>
    </section>

    <section id="mapping-declaration-id" revision="4">
      <title>Identifiers

      <para>Mapped classes must declare the primary key
      column of the database table. Most classes will also have a
      JavaBeans-style property holding the unique identifier of an
      instance.</para>

      <para>Mark the identifier property with
      <classname>@Id.

      <programlisting role="JAVA">@Entity
public class Person {
   @Id Integer getId() { ... }
   ...
}</programlisting>

      <para>In hbm.xml, use the <id> element which
      defines the mapping from that property to the primary key column.</para>

      <programlistingco role="XML">
        <areaspec>
          <area coords="2" id="id1" />

          <area coords="3" id="id2" />

          <area coords="4" id="id3" />

          <area coords="5" id="id4" />

          <area coords="6" id="id5" />
        </areaspec>

        <programlisting><id
        name="propertyName"
        type="typename"
        column="column_name"
        unsaved-value="null|any|none|undefined|id_value"
        access="field|property|ClassName">
        node="element-name|@attribute-name|element/@attribute|."

        <generator class="generatorClass"/>
</id></programlisting>

        <calloutlist>
          <callout arearefs="id1">
            <para>name (optional): the name of the
            identifier property.</para>
          </callout>

          <callout arearefs="id2">
            <para>type (optional): a name that indicates
            the Hibernate type.</para>
          </callout>

          <callout arearefs="id3">
            <para>column (optional - defaults to the
            property name): the name of the primary key column.</para>
          </callout>

          <callout arearefs="id4">
            <para>unsaved-value (optional - defaults to a
            "sensible" value): an identifier property value that indicates an
            instance is newly instantiated (unsaved), distinguishing it from
            detached instances that were saved or loaded in a previous
            session.</para>
          </callout>

          <callout arearefs="id5">
            <para>access (optional - defaults to
            <literal>property): the strategy Hibernate should use
            for accessing the property value.</para>
          </callout>
        </calloutlist>
      </programlistingco>

      <para>If the name attribute is missing, it is assumed
      that the class has no identifier property.</para>

      <para>The unsaved-value attribute is almost never
      needed in Hibernate3 and indeed has no corresponding element in
      annotations.</para>

      <para>You can also declare the identifier as a composite identifier.
      This allows access to legacy data with composite keys. Its use is
      strongly discouraged for anything else.</para>

      <section>
        <title>Composite identifier

        <para>You can define a composite primary key through several
        syntaxes:</para>

        <itemizedlist>
          <listitem>
            <para>use a component type to represent the identifier and map it
            as a property in the entity: you then annotated the property as
            <classname>@EmbeddedId. The component type has to be
            <classname>Serializable.
          </listitem>

          <listitem>
            <para>map multiple properties as @Id
            properties: the identifier type is then the entity class itself
            and needs to be <classname>Serializable. This approach
            is unfortunately not standard and only supported by
            Hibernate.</para>
          </listitem>

          <listitem>
            <para>map multiple properties as @Id
            properties and declare an external class to be the identifier
            type. This class, which needs to be
            <classname>Serializable, is declared on the entity via
            the <classname>@IdClass annotation. The identifier
            type must contain the same properties as the identifier properties
            of the entity: each property name must be the same, its type must
            be the same as well if the entity property is of a basic type, its
            type must be the type of the primary key of the associated entity
            if the entity property is an association (either a
            <classname>@OneToOne or a
            <classname>@ManyToOne).
          </listitem>
        </itemizedlist>

        <para>As you can see the last case is far from obvious. It has been
        inherited from the dark ages of EJB 2 for backward compatibilities and
        we recommend you not to use it (for simplicity sake).</para>

        <para>Let's explore all three cases using examples.

        <section>
          <title>id as a property using a component type

          <para>Here is a simple example of
          <classname>@EmbeddedId.

          <programlisting language="JAVA" role="JAVA">@Entity
class User {
   @EmbeddedId
   @AttributeOverride(name="firstName", column=@Column(name="fld_firstname")
   UserId id;

   Integer age;
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;
}</programlisting>

          <para>You can notice that the UserId class is
          serializable. To override the column mapping, use
          <classname>@AttributeOverride.

          <para>An embedded id can itself contains the primary key of an
          associated entity.</para>

          <programlisting language="JAVA" role="JAVA">@Entity
class Customer {
   @EmbeddedId CustomerId id;
   boolean preferredCustomer;

   @MapsId("userId")
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   })
   @OneToOne User user;
}

@Embeddable
class CustomerId implements Serializable {
   UserId userId;
   String customerNumber;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;

   //implements equals and hashCode
}</programlisting>

          <para>In the embedded id object, the association is represented as
          the identifier of the associated entity. But you can link its value
          to a regular association in the entity via the
          <classname>@MapsId annotation. The
          <classname>@MapsId value correspond to the property name
          of the embedded id object containing the associated entity's
          identifier. In the database, it means that the
          <literal>Customer.user and the
          <literal>CustomerId.userId properties share the same
          underlying column (<literal>user_fk in this case).

          <tip>
            <para>The component type used as identifier must implement
            <methodname>equals() and
            <methodname>hashCode().
          </tip>

          <para>In practice, your code only sets the
          <literal>Customer.user property and the user id value is
          copied by Hibernate into the <literal>CustomerId.userId
          property.</para>

          <warning>
            <para>The id value can be copied as late as flush time, don't rely
            on it until after flush time.</para>
          </warning>

          <para>While not supported in JPA, Hibernate lets you place your
          association directly in the embedded id component (instead of having
          to use the <classname>@MapsId annotation).

          <programlisting language="JAVA" role="JAVA">@Entity
class Customer {
   @EmbeddedId CustomerId id;
   boolean preferredCustomer;
}

@Embeddable
class CustomerId implements Serializable {
   @OneToOne
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   }) 
   User user;
   String customerNumber;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;


   //implements equals and hashCode
}</programlisting>

          <para>Let's now rewrite these examples using the hbm.xml
          syntax.</para>

          <programlisting role="XML"><composite-id
        name="propertyName"
        class="ClassName"
        mapped="true|false"
        access="field|property|ClassName"
        node="element-name|.">

        <key-property name="propertyName" type="typename" column="column_name"/>
        <key-many-to-one name="propertyName" class="ClassName" column="column_name"/>
        ......
</composite-id></programlisting>

          <para>First a simple example:

          <programlisting role="XML"><class name="User">
   <composite-id name="id" class="UserId">
      <key-property name="firstName" column="fld_firstname"/>
      <key-property name="lastName"/>
   </composite-id>
</class></programlisting>

          <para>Then an example showing how an association can be
          mapped.</para>

          <programlisting role="XML"><class name="Customer">
   <composite-id name="id" class="CustomerId">
      <key-property name="firstName" column="userfirstname_fk"/>
      <key-property name="lastName" column="userfirstname_fk"/>
      <key-property name="customerNumber"/>
   </composite-id>

   <property name="preferredCustomer"/>

   <many-to-one name="user">
      <column name="userfirstname_fk" updatable="false" insertable="false"/>
      <column name="userlastname_fk" updatable="false" insertable="false"/>
   </many-to-one>
</class>

<class name="User">
   <composite-id name="id" class="UserId">
      <key-property name="firstName"/>
      <key-property name="lastName"/>
   </composite-id>

   <property name="age"/>
</class></programlisting>

          <para>Notice a few things in the previous example:

          <itemizedlist>
            <listitem>
              <para>the order of the properties (and column) matters. It must
              be the same between the association and the primary key of the
              associated entity</para>
            </listitem>

            <listitem>
              <para>the many to one uses the same columns as the primary key
              and thus must be marked as read only
              (<literal>insertable and updatable
              to false).</para>
            </listitem>

            <listitem>
              <para>unlike with @MapsId, the id value
              of the associated entity is not transparently copied, check the
              <literal>foreign id generator for more
              information.</para>
            </listitem>
          </itemizedlist>

          <para>The last example shows how to map association directly in the
          embedded id component.</para>

          <programlisting role="XML"><class name="Customer">
   <composite-id name="id" class="CustomerId">
      <key-many-to-one name="user">
         <column name="userfirstname_fk"/>
         <column name="userlastname_fk"/>
      </key-many-to-one>
      <key-property name="customerNumber"/>
   </composite-id>

   <property name="preferredCustomer"/>
</class>

<class name="User">
   <composite-id name="id" class="UserId">
      <key-property name="firstName"/>
      <key-property name="lastName"/>
   </composite-id>

   <property name="age"/>
</class></programlisting>

          <para>This is the recommended approach to map composite identifier.
          The following options should not be considered unless some
          constraint are present.</para>
        </section>

        <section>
          <title>Multiple id properties without identifier type

          <para>Another, arguably more natural, approach is to place
          <classname>@Id on multiple properties of your entity.
          This approach is only supported by Hibernate (not JPA compliant) but
          does not require an extra embeddable component.</para>

          <programlisting language="JAVA" role="JAVA">@Entity
class Customer implements Serializable {
   @Id @OneToOne
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   })
   User user;
  
   @Id String customerNumber;

   boolean preferredCustomer;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;

   //implements equals and hashCode
}</programlisting>

          <para>In this case Customer is its own
          identifier representation: it must implement
          <classname>Serializable and must implement
          <methodname>equals() and
          <methodname>hashCode().

          <para>In hbm.xml, the same mapping is:

          <programlisting role="XML"><class name="Customer">
   <composite-id>
      <key-many-to-one name="user">
         <column name="userfirstname_fk"/>
         <column name="userlastname_fk"/>
      </key-many-to-one>
      <key-property name="customerNumber"/>
   </composite-id>

   <property name="preferredCustomer"/>
</class>

<class name="User">
   <composite-id name="id" class="UserId">
      <key-property name="firstName"/>
      <key-property name="lastName"/>
   </composite-id>

   <property name="age"/>
</class></programlisting>
        </section>

        <section>
          <title>Multiple id properties with with a dedicated identifier
          type</title>

          <para>@IdClass on an entity points to the
          class (component) representing the identifier of the class. The
          properties marked <classname>@Id on the entity must have
          their corresponding property on the <classname>@IdClass.
          The return type of search twin property must be either identical for
          basic properties or must correspond to the identifier class of the
          associated entity for an association.</para>

          <warning>
            <para>This approach is inherited from the EJB 2 days and we
            recommend against its use. But, after all it's your application
            and Hibernate supports it.</para>
          </warning>

          <programlisting language="JAVA" role="JAVA">@Entity
@IdClass(CustomerId.class)
class Customer implements Serializable {
   @Id @OneToOne
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   }) 
   User user;
  
   @Id String customerNumber;

   boolean preferredCustomer;
}

class CustomerId implements Serializable {
   UserId user;
   String customerNumber;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;

   //implements equals and hashCode
}

@Embeddable
class UserId implements Serializable {
   String firstName;
   String lastName;

   //implements equals and hashCode
}</programlisting>

          <para>Customer and
          <classname>CustomerId do have the same properties
          <literal>customerNumber as well as
          <literal>user. CustomerId must be
          <classname>Serializable and implement
          <classname>equals() and
          <classname>hashCode().

          <para>While not JPA standard, Hibernate let's you declare the
          vanilla associated property in the
          <classname>@IdClass.

          <programlisting language="JAVA" role="JAVA">@Entity
@IdClass(CustomerId.class)
class Customer implements Serializable {
   @Id @OneToOne
   @JoinColumns({
      @JoinColumn(name="userfirstname_fk", referencedColumnName="firstName"),
      @JoinColumn(name="userlastname_fk", referencedColumnName="lastName")
   }) 
   User user;
  
   @Id String customerNumber;

   boolean preferredCustomer;
}

class CustomerId implements Serializable {
   @OneToOne User user;
   String customerNumber;

   //implements equals and hashCode
}

@Entity 
class User {
   @EmbeddedId UserId id;
   Integer age;

   //implements equals and hashCode
}

@Embeddable
class UserId implements Serializable {
  String firstName;
  String lastName;
}</programlisting>

          <para>This feature is of limited interest though as you are likely
          to have chosen the <classname>@IdClass approach to stay
          JPA compliant or you have a quite twisted mind.</para>

          <para>Here are the equivalent on hbm.xml files:

          <programlisting role="XML"><class name="Customer">
   <composite-id class="CustomerId" mapped="true">
      <key-many-to-one name="user">
         <column name="userfirstname_fk"/>
         <column name="userlastname_fk"/>
      </key-many-to-one>
      <key-property name="customerNumber"/>
   </composite-id>

   <property name="preferredCustomer"/>
</class>

<class name="User">
   <composite-id name="id" class="UserId">
      <key-property name="firstName"/>
      <key-property name="lastName"/>
   </composite-id>

   <property name="age"/>
</class></programlisting>
        </section>
      </section>

      <section id="mapping-declaration-id-generator" revision="2">
        <title>Identifier generator

        <para>Hibernate can generate and populate identifier values for you
        automatically. This is the recommended approach over "business" or
        "natural" id (especially composite ids).</para>

        <para>Hibernate offers various generation strategies, let's explore
        the most common ones first that happens to be standardized by
        JPA:</para>

        <itemizedlist>
          <listitem>
            <para>IDENTITY: supports identity columns in DB2, MySQL, MS SQL
            Server, Sybase and HypersonicSQL. The returned identifier is of
            type <literal>long, short or
            <literal>int.
          </listitem>

          <listitem>
            <para>SEQUENCE (called seqhilo in Hibernate):
            uses a hi/lo algorithm to efficiently generate identifiers of type
            <literal>long, short or
            <literal>int, given a named database sequence.
          </listitem>

          <listitem>
            <para>TABLE (called
            <classname>MultipleHiLoPerTableGenerator in Hibernate)
            : uses a hi/lo algorithm to efficiently generate identifiers of
            type <literal>long, short or
            <literal>int, given a table and column as a source of hi
            values. The hi/lo algorithm generates identifiers that are unique
            only for a particular database.</para>
          </listitem>

          <listitem>
            <para>AUTO: selects IDENTITY,
            <literal>SEQUENCE or TABLE depending
            upon the capabilities of the underlying database.</para>
          </listitem>
        </itemizedlist>

        <important>
          <para>We recommend all new projects to use the new enhanced
          identifier generators. They are deactivated by default for entities
          using annotations but can be activated using
          <code>hibernate.id.new_generator_mappings=true. These new
          generators are more efficient and closer to the JPA 2 specification
          semantic.</para>

          <para>However they are not backward compatible with existing
          Hibernate based application (if a sequence or a table is used for id
          generation). See XXXXXXX <xref linkend="ann-setup-properties" /> for
          more information on how to activate them.</para>
        </important>

        <para>To mark an id property as generated, use the
        <classname>@GeneratedValue annotation. You can specify the
        strategy used (default to <literal>AUTO) by setting
        <literal>strategy.

        <programlisting role="JAVA">@Entity
public class Customer {
   @Id @GeneratedValue
   Integer getId() { ... };
}

@Entity 
public class Invoice {
   @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
   Integer getId() { ... };
}</programlisting>

        <para>SEQUENCE and TABLE require
        additional configurations that you can set using
        <classname>@SequenceGenerator and
        <classname>@TableGenerator:

        <itemizedlist>
          <listitem>
            <para>name: name of the generator
          </listitem>

          <listitem>
            <para>table / sequenceName:
            name of the table or the sequence (defaulting respectively to
            <literal>hibernate_sequences and
            <literal>hibernate_sequence)
          </listitem>

          <listitem>
            <para>catalog /
            <literal>schema:
          </listitem>

          <listitem>
            <para>initialValue: the value from which the id
            is to start generating</para>
          </listitem>

          <listitem>
            <para>allocationSize: the amount to increment
            by when allocating id numbers from the generator</para>
          </listitem>
        </itemizedlist>

        <para>In addition, the TABLE strategy also let
        you customize:</para>

        <itemizedlist>
          <listitem>
            <para>pkColumnName: the column name containing
            the entity identifier</para>
          </listitem>

          <listitem>
            <para>valueColumnName: the column name
            containing the identifier value</para>
          </listitem>

          <listitem>
            <para>pkColumnValue: the entity
            identifier</para>
          </listitem>

          <listitem>
            <para>uniqueConstraints: any potential column
            constraint on the table containing the ids</para>
          </listitem>
        </itemizedlist>

        <para>To link a table or sequence generator definition with an actual
        generated property, use the same name in both the definition
        <literal>name and the generator value
        <literal>generator as shown below.

        <programlisting language="JAVA" role="JAVA">@Id 
@GeneratedValue(
    strategy=GenerationType.SEQUENCE, 
    generator="SEQ_GEN")
@javax.persistence.SequenceGenerator(
    name="SEQ_GEN",
    sequenceName="my_sequence",
    allocationSize=20
)
public Integer getId() { ... }        </programlisting>

        <para>The scope of a generator definition can be the application or
        the class. Class-defined generators are not visible outside the class
        and can override application level generators. Application level
        generators are defined in JPA's XML deployment descriptors (see XXXXXX
        <xref linkend="xml-overriding" />):

        <programlisting language="JAVA" role="JAVA"><table-generator name="EMP_GEN"
            table="GENERATOR_TABLE"
            pk-column-name="key"
            value-column-name="hi"
            pk-column-value="EMP"
            allocation-size="20"/>

//and the annotation equivalent

@javax.persistence.TableGenerator(
    name="EMP_GEN",
    table="GENERATOR_TABLE",
    pkColumnName = "key",
    valueColumnName = "hi"
    pkColumnValue="EMP",
    allocationSize=20
)

<sequence-generator name="SEQ_GEN" 
    sequence-name="my_sequence"
    allocation-size="20"/>

//and the annotation equivalent

@javax.persistence.SequenceGenerator(
    name="SEQ_GEN",
    sequenceName="my_sequence",
    allocationSize=20
)
         </programlisting>

        <para>If a JPA XML descriptor (like
        <filename>META-INF/orm.xml) is used to define the
        generators, <literal>EMP_GEN and SEQ_GEN
        are application level generators.</para>

        <note>
          <para>Package level definition is not supported by the JPA
          specification. However, you can use the
          <literal>@GenericGenerator at the package level (see 
        </note>

        <para>These are the four standard JPA generators. Hibernate goes
        beyond that and provide additional generators or additional options as
        we will see below. You can also write your own custom identifier
        generator by implementing
        <classname>org.hibernate.id.IdentifierGenerator.

        <para>To define a custom generator, use the
        <classname>@GenericGenerator annotation (and its plural
        counter part <classname>@GenericGenerators) that describes
        the class of the identifier generator or its short cut name (as
        described below) and a list of key/value parameters. When using
        <classname>@GenericGenerator and assigning it via
        <classname>@GeneratedValue.generator, the
        <classname>@GeneratedValue.strategy is ignored: leave it
        blank.</para>

        <programlisting language="JAVA" role="JAVA">@Id @GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
public String getId() {

@Id @GeneratedValue(generator="trigger-generated")
@GenericGenerator(
    name="trigger-generated", 
    strategy = "select",
    parameters = @Parameter(name="key", value = "socialSecurityNumber")
)
public String getId() {</programlisting>

        <para>The hbm.xml approach uses the optional
        <literal><generator> child element inside
        <literal><id>. If any parameters are required to
        configure or initialize the generator instance, they are passed using
        the <literal><param> element.

        <programlisting role="XML"><id name="id" type="long" column="cat_id">
        <generator class="org.hibernate.id.TableHiLoGenerator">
                <param name="table">uid_table</param>
                <param name="column">next_hi_value_column</param>
        </generator>
</id></programlisting>

        <section>
          <title>Various additional generators

          <para>All generators implement the interface
          <literal>org.hibernate.id.IdentifierGenerator. This is a
          very simple interface. Some applications can choose to provide their
          own specialized implementations, however, Hibernate provides a range
          of built-in implementations. The shortcut names for the built-in
          generators are as follows: <variablelist>
              <varlistentry>
                <term>increment

                <listitem>
                  <para>generates identifiers of type long,
                  <literal>short or int that are
                  unique only when no other process is inserting data into the
                  same table. <emphasis>Do not use in a
                  cluster.</emphasis>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>identity

                <listitem>
                  <para>supports identity columns in DB2, MySQL, MS SQL
                  Server, Sybase and HypersonicSQL. The returned identifier is
                  of type <literal>long, short or
                  <literal>int.
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>sequence

                <listitem>
                  <para>uses a sequence in DB2, PostgreSQL, Oracle, SAP DB,
                  McKoi or a generator in Interbase. The returned identifier
                  is of type <literal>long, short
                  or <literal>int
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>hilo

                <listitem>
                  <para id="mapping-declaration-id-hilodescription"
                  revision="1">uses a hi/lo algorithm to efficiently generate
                  identifiers of type <literal>long,
                  <literal>short or int, given a
                  table and column (by default
                  <literal>hibernate_unique_key and
                  <literal>next_hi respectively) as a source of hi
                  values. The hi/lo algorithm generates identifiers that are
                  unique only for a particular database.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>seqhilo

                <listitem>
                  <para>uses a hi/lo algorithm to efficiently generate
                  identifiers of type <literal>long,
                  <literal>short or int, given a
                  named database sequence.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>uuid

                <listitem>
                  <para>Generates a 128-bit UUID based on a custom algorithm.
                  The value generated is represented as a string of 32
                  hexidecimal digits. Users can also configure it to use a
                  separator (config parameter "separator") which separates the
                  hexidecimal digits into 8{sep}8{sep}4{sep}8{sep}4. Note
                  specifically that this is different than the IETF RFC 4122
                  representation of 8-4-4-4-12. If you need RFC 4122 compliant
                  UUIDs, consider using "uuid2" generator discussed
                  below.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>uuid2

                <listitem>
                  <para>Generates a IETF RFC 4122 compliant (variant 2)
                  128-bit UUID. The exact "version" (the RFC term) generated
                  depends on the pluggable "generation strategy" used (see
                  below). Capable of generating values as
                  <classname>java.util.UUID,
                  <classname>java.lang.String or as a byte array
                  of length 16 (<literal>byte[16]). The "generation
                  strategy" is defined by the interface
                  <interfacename>org.hibernate.id.UUIDGenerationStrategy.
                  The generator defines 2 configuration parameters for
                  defining which generation strategy to use: <variablelist>
                      <varlistentry>
                        <term>uuid_gen_strategy_class

                        <listitem>
                          <para>Names the UUIDGenerationStrategy class to
                          use</para>
                        </listitem>
                      </varlistentry>

                      <varlistentry>
                        <term>uuid_gen_strategy

                        <listitem>
                          <para>Names the UUIDGenerationStrategy instance to
                          use</para>
                        </listitem>
                      </varlistentry>
                    </variablelist>

                  <para>Out of the box, comes with the following strategies:
                  <itemizedlist>
                      <listitem>
                        <para>org.hibernate.id.uuid.StandardRandomStrategy
                        (the default) - generates "version 3" (aka, "random")
                        UUID values via the
                        <methodname>randomUUID method of
                        <classname>java.util.UUID
                      </listitem>

                      <listitem>
                        <para>org.hibernate.id.uuid.CustomVersionOneStrategy
                        - generates "version 1" UUID values, using IP address
                        since mac address not available. If you need mac
                        address to be used, consider leveraging one of the
                        existing third party UUID generators which sniff out
                        mac address and integrating it via the
                        <interfacename>org.hibernate.id.UUIDGenerationStrategy
                        contract. Two such libraries known at time of this
                        writing include <ulink
                        url="http://johannburkard.de/software/uuid/">http://johannburkard.de/software/uuid/</ulink>
                        and <ulink
                        url="http://commons.apache.org/sandbox/id/uuid.html">http://commons.apache.org/sandbox/id/uuid.html</ulink>
                      </listitem>
                    </itemizedlist>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>guid

                <listitem>
                  <para>uses a database-generated GUID string on MS SQL Server
                  and MySQL.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>native

                <listitem>
                  <para>selects identity,
                  <literal>sequence or hilo
                  depending upon the capabilities of the underlying
                  database.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>assigned

                <listitem>
                  <para>lets the application assign an identifier to the
                  object before <literal>save() is called. This is
                  the default strategy if no
                  <literal><generator> element is
                  specified.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>select

                <listitem>
                  <para>retrieves a primary key, assigned by a database
                  trigger, by selecting the row by some unique key and
                  retrieving the primary key value.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>foreign

                <listitem>
                  <para>uses the identifier of another associated object. It
                  is usually used in conjunction with a
                  <literal><one-to-one> primary key
                  association.</para>
                </listitem>
              </varlistentry>

              <varlistentry>
                <term>sequence-identity

                <listitem>
                  <para>a specialized sequence generation strategy that
                  utilizes a database sequence for the actual value
                  generation, but combines this with JDBC3 getGeneratedKeys to
                  return the generated identifier value as part of the insert
                  statement execution. This strategy is only supported on
                  Oracle 10g drivers targeted for JDK 1.4. Comments on these
                  insert statements are disabled due to a bug in the Oracle
                  drivers.</para>
                </listitem>
              </varlistentry>
            </variablelist>
        </section>

        <section id="mapping-declaration-id-hilo" revision="1">
          <title>Hi/lo algorithm

          <para>The hilo and seqhilo
          generators provide two alternate implementations of the hi/lo
          algorithm. The first implementation requires a "special" database
          table to hold the next available "hi" value. Where supported, the
          second uses an Oracle-style sequence.</para>

          <programlisting role="XML"><id name="id" type="long" column="cat_id">
        <generator class="hilo">
                <param name="table">hi_value</param>
                <param name="column">next_value</param>
                <param name="max_lo">100</param>
        </generator>
</id></programlisting>

          <programlisting role="XML"><id name="id" type="long" column="cat_id">
        <generator class="seqhilo">
                <param name="sequence">hi_value</param>
                <param name="max_lo">100</param>
        </generator>
</id></programlisting>

          <para>Unfortunately, you cannot use hilo when
          supplying your own <literal>Connection to Hibernate. When
          Hibernate uses an application server datasource to obtain
          connections enlisted with JTA, you must configure the
          <literal>hibernate.transaction.manager_lookup_class.
        </section>

        <section id="mapping-declaration-id-uuid">
          <title>UUID algorithm

          <para>The UUID contains: IP address, startup time of the JVM that is
          accurate to a quarter second, system time and a counter value that
          is unique within the JVM. It is not possible to obtain a MAC address
          or memory address from Java code, so this is the best option without
          using JNI.</para>
        </section>

        <section id="mapping-declaration-id-sequences">
          <title>Identity columns and sequences

          <para>For databases that support identity columns (DB2, MySQL,
          Sybase, MS SQL), you can use <literal>identity key
          generation. For databases that support sequences (DB2, Oracle,
          PostgreSQL, Interbase, McKoi, SAP DB) you can use
          <literal>sequence style key generation. Both of these
          strategies require two SQL queries to insert a new object. For
          example:</para>

          <programlisting role="XML"><id name="id" type="long" column="person_id">
        <generator class="sequence">
                <param name="sequence">person_id_sequence</param>
        </generator>
</id></programlisting>

          <programlisting role="XML"><id name="id" type="long" column="person_id" unsaved-value="0">
        <generator class="identity"/>
</id></programlisting>

          <para>For cross-platform development, the native
          strategy will, depending on the capabilities of the underlying
          database, choose from the <literal>identity,
          <literal>sequence and hilo
          strategies.</para>
        </section>

        <section id="mapping-declaration-id-assigned">
          <title>Assigned identifiers

          <para>If you want the application to assign identifiers, as opposed
          to having Hibernate generate them, you can use the
          <literal>assigned generator. This special generator uses
          the identifier value already assigned to the object's identifier
          property. The generator is used when the primary key is a natural
          key instead of a surrogate key. This is the default behavior if you
          do not specify <classname>@GeneratedValue nor
          <literal><generator> elements.

          <para>The assigned generator makes Hibernate use
          <literal>unsaved-value="undefined". This forces Hibernate
          to go to the database to determine if an instance is transient or
          detached, unless there is a version or timestamp property, or you
          define <literal>Interceptor.isUnsaved().
        </section>

        <section id="mapping-declaration-id-select">
          <title>Primary keys assigned by triggers

          <para>Hibernate does not generate DDL with triggers. It is for
          legacy schemas only.</para>

          <programlisting role="XML"><id name="id" type="long" column="person_id">
        <generator class="select">
                <param name="key">socialSecurityNumber</param>
        </generator>
</id></programlisting>

          <para>In the above example, there is a unique valued property named
          <literal>socialSecurityNumber. It is defined by the class,
          as a natural key and a surrogate key named
          <literal>person_id, whose value is generated by a
          trigger.</para>
        </section>

        <section>
          <title>Identity copy (foreign generator)

          <para>Finally, you can ask Hibernate to copy the identifier from
          another associated entity. In the Hibernate jargon, it is known as a
          foreign generator but the JPA mapping reads better and is
          encouraged.</para>

          <programlisting language="JAVA" role="JAVA">@Entity
class MedicalHistory implements Serializable {
  @Id @OneToOne
  @JoinColumn(name = "person_id")
  Person patient;
}

@Entity
public class Person implements Serializable {
  @Id @GeneratedValue Integer id;
}</programlisting>

          <para>Or alternatively

          <programlisting language="JAVA" role="JAVA">@Entity
class MedicalHistory implements Serializable {
  @Id Integer id;

  @MapsId @OneToOne
  @JoinColumn(name = "patient_id")
  Person patient;
}

@Entity
class Person {
  @Id @GeneratedValue Integer id;
}</programlisting>

          <para>In hbm.xml use the following approach:

          <programlisting role="XML"><class name="MedicalHistory">
   <id name="id">
      <generator class="foreign">
         <param name="property">patient</param>
      </generator>
   </id>
   <one-to-one name="patient" class="Person" constrained="true"/>
</class></programlisting>
        </section>
      </section>

      <section id="mapping-declaration-id-enhanced">
        <title>Enhanced identifier generators

        <para>Starting with release 3.2.3, there are 2 new generators which
        represent a re-thinking of 2 different aspects of identifier
        generation. The first aspect is database portability; the second is
        optimization Optimization means that you do not have to query the
        database for every request for a new identifier value. These two new
        generators are intended to take the place of some of the named
        generators described above, starting in 3.3.x. However, they are
        included in the current releases and can be referenced by FQN.</para>

        <para>The first of these new generators is
        <literal>org.hibernate.id.enhanced.SequenceStyleGenerator
        which is intended, firstly, as a replacement for the
        <literal>sequence generator and, secondly, as a better
        portability generator than <literal>native. This is because
        <literal>native generally chooses between
        <literal>identity and sequence which have
        largely different semantics that can cause subtle issues in
        applications eyeing portability.
        <literal>org.hibernate.id.enhanced.SequenceStyleGenerator,
        however, achieves portability in a different manner. It chooses
        between a table or a sequence in the database to store its
        incrementing values, depending on the capabilities of the dialect
        being used. The difference between this and <literal>native
        is that table-based and sequence-based storage have the same exact
        semantic. In fact, sequences are exactly what Hibernate tries to
        emulate with its table-based generators. This generator has a number
        of configuration parameters: <itemizedlist spacing="compact">
            <listitem>
              <para>sequence_name (optional, defaults to
              <literal>hibernate_sequence): the name of the sequence
              or table to be used.</para>
            </listitem>

            <listitem>
              <para>initial_value (optional, defaults to
              <literal>1): the initial value to be retrieved from
              the sequence/table. In sequence creation terms, this is
              analogous to the clause typically named "STARTS WITH".</para>
            </listitem>

            <listitem>
              <para>increment_size (optional - defaults to
              <literal>1): the value by which subsequent calls to
              the sequence/table should differ. In sequence creation terms,
              this is analogous to the clause typically named "INCREMENT
              BY".</para>
            </listitem>

            <listitem>
              <para>force_table_use (optional - defaults to
              <literal>false): should we force the use of a table as
              the backing structure even though the dialect might support
              sequence?</para>
            </listitem>

            <listitem>
              <para>value_column (optional - defaults to
              <literal>next_val): only relevant for table
              structures, it is the name of the column on the table which is
              used to hold the value.</para>
            </listitem>

            <listitem>
              <para>optimizer (optional - defaults to
              <literal>none): See 
            </listitem>
          </itemizedlist>

        <para>The second of these new generators is
        <literal>org.hibernate.id.enhanced.TableGenerator, which is
        intended, firstly, as a replacement for the <literal>table
        generator, even though it actually functions much more like
        <literal>org.hibernate.id.MultipleHiLoPerTableGenerator, and
        secondly, as a re-implementation of
        <literal>org.hibernate.id.MultipleHiLoPerTableGenerator that
        utilizes the notion of pluggable optimizers. Essentially this
        generator defines a table capable of holding a number of different
        increment values simultaneously by using multiple distinctly keyed
        rows. This generator has a number of configuration parameters:
        <itemizedlist spacing="compact">
            <listitem>
              <para>table_name (optional - defaults to
              <literal>hibernate_sequences): the name of the table
              to be used.</para>
            </listitem>

            <listitem>
              <para>value_column_name (optional - defaults
              to <literal>next_val): the name of the column on the
              table that is used to hold the value.</para>
            </listitem>

            <listitem>
              <para>segment_column_name (optional -
              defaults to <literal>sequence_name): the name of the
              column on the table that is used to hold the "segment key". This
              is the value which identifies which increment value to
              use.</para>
            </listitem>

            <listitem>
              <para>segment_value (optional - defaults to
              <literal>default): The "segment key" value for the
              segment from which we want to pull increment values for this
              generator.</para>
            </listitem>

            <listitem>
              <para>segment_value_length (optional -
              defaults to <literal>255): Used for schema generation;
              the column size to create this segment key column.</para>
            </listitem>

            <listitem>
              <para>initial_value (optional - defaults to
              <literal>1): The initial value to be retrieved from
              the table.</para>
            </listitem>

            <listitem>
              <para>increment_size (optional - defaults to
              <literal>1): The value by which subsequent calls to
              the table should differ.</para>
            </listitem>

            <listitem>
              <para>optimizer (optional - defaults to
              <literal>??): See 
            </listitem>
          </itemizedlist>

        <section id="mapping-declaration-id-enhanced-optimizers">
          <title>Identifier generator optimization

          <para>For identifier generators that store values in the database,
          it is inefficient for them to hit the database on each and every
          call to generate a new identifier value. Instead, you can group a
          bunch of them in memory and only hit the database when you have
          exhausted your in-memory value group. This is the role of the
          pluggable optimizers. Currently only the two enhanced generators
          (<xref linkend="mapping-declaration-id-enhanced" /> support this
          operation.</para>

          <itemizedlist spacing="compact">
            <listitem>
              <para>none (generally this is the default if
              no optimizer was specified): this will not perform any
              optimizations and hit the database for each and every
              request.</para>
            </listitem>

            <listitem>
              <para>hilo: applies a hi/lo algorithm around
              the database retrieved values. The values from the database for
              this optimizer are expected to be sequential. The values
              retrieved from the database structure for this optimizer
              indicates the "group number". The
              <literal>increment_size is multiplied by that value in
              memory to define a group "hi value".</para>
            </listitem>

            <listitem>
              <para>pooled: as with the case of
              <literal>hilo, this optimizer attempts to minimize the
              number of hits to the database. Here, however, we simply store
              the starting value for the "next group" into the database
              structure rather than a sequential value in combination with an
              in-memory grouping algorithm. Here,
              <literal>increment_size refers to the values coming
              from the database.</para>
            </listitem>
          </itemizedlist>
        </section>
      </section>

      <section>
        <title>Partial identifier generation

        <para>Hibernate supports the automatic generation of some of the
        identifier properties. Simply use the
        <classname>@GeneratedValue annotation on one or several id
        properties.</para>

        <warning>
          <para>The Hibernate team has always felt such a construct as
          fundamentally wrong. Try hard to fix your data model before using
          this feature.</para>
        </warning>

        <programlisting language="JAVA" role="JAVA">@Entity
public class CustomerInventory implements Serializable {
  @Id
  @TableGenerator(name = "inventory",
    table = "U_SEQUENCES",
    pkColumnName = "S_ID",
    valueColumnName = "S_NEXTNUM",
    pkColumnValue = "inventory",
    allocationSize = 1000)
  @GeneratedValue(strategy = GenerationType.TABLE, generator = "inventory")
  Integer id;


  @Id @ManyToOne(cascade = CascadeType.MERGE)
  Customer customer;
}

@Entity
public class Customer implements Serializable {
   @Id
   private int id;
}</programlisting>

        <para>You can also generate properties inside an
        <classname>@EmbeddedId class.
      </section>
    </section>

    <section>
      <title>Optimistic locking properties (optional)

      <para>When using long transactions or conversations that span several
      database transactions, it is useful to store versioning data to ensure
      that if the same entity is updated by two conversations, the last to
      commit changes will be informed and not override the other
      conversation's work. It guarantees some isolation while still allowing
      for good scalability and works particularly well in read-often
      write-sometimes situations.</para>

      <para>You can use two approaches: a dedicated version number or a
      timestamp.</para>

      <para>A version or timestamp property should never be null for a
      detached instance. Hibernate will detect any instance with a null
      version or timestamp as transient, irrespective of what other
      <literal>unsaved-value strategies are specified.
      <emphasis>Declaring a nullable version or timestamp property is an easy
      way to avoid problems with transitive reattachment in Hibernate. It is
      especially useful for people using assigned identifiers or composite
      keys</emphasis>.

      <section id="entity-mapping-entity-version">
        <title>Version number

        <para>You can add optimistic locking capability to an entity using the
        <literal>@Version annotation:

        <programlisting language="JAVA" role="JAVA">@Entity
public class Flight implements Serializable {
...
    @Version
    @Column(name="OPTLOCK")
    public Integer getVersion() { ... }
}           </programlisting>

        <para>The version property will be mapped to the
        <literal>OPTLOCK column, and the entity manager will use it
        to detect conflicting updates (preventing lost updates you might
        otherwise see with the last-commit-wins strategy).</para>

        <para>The version column may be a numeric. Hibernate supports any kind
        of type provided that you define and implement the appropriate
        <classname>UserVersionType.

        <para>The application must not alter the version number set up by
        Hibernate in any way. To artificially increase the version number,
        check in Hibernate Entity Manager's reference documentation
        <literal>LockModeType.OPTIMISTIC_FORCE_INCREMENT or
        <literal>LockModeType.PESSIMISTIC_FORCE_INCREMENT.

        <para>If the version number is generated by the database (via a
        trigger for example), make sure to use
        <code>@org.hibernate.annotations.Generated(GenerationTime.ALWAYS).

        <para>To declare a version property in hbm.xml, use:

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="version1" />

            <area coords="3" id="version2" />

            <area coords="4" id="version3" />

            <area coords="5" id="version4" />

            <area coords="6" id="version5" />

            <area coords="7" id="version6" />

            <area coords="8" id="version7" />
          </areaspec>

          <programlisting><version
        column="version_column"
        name="propertyName"
        type="typename"
        access="field|property|ClassName"
        unsaved-value="null|negative|undefined"
        generated="never|always"
        insert="true|false"
        node="element-name|@attribute-name|element/@attribute|."
/></programlisting>

          <calloutlist>
            <callout arearefs="version1">
              <para>column (optional - defaults to the
              property name): the name of the column holding the version
              number.</para>
            </callout>

            <callout arearefs="version2">
              <para>name: the name of a property of the
              persistent class.</para>
            </callout>

            <callout arearefs="version3">
              <para>type (optional - defaults to
              <literal>integer): the type of the version
              number.</para>
            </callout>

            <callout arearefs="version4">
              <para>access (optional - defaults to
              <literal>property): the strategy Hibernate uses to
              access the property value.</para>
            </callout>

            <callout arearefs="version5">
              <para>unsaved-value (optional - defaults to
              <literal>undefined): a version property value that
              indicates that an instance is newly instantiated (unsaved),
              distinguishing it from detached instances that were saved or
              loaded in a previous session. <literal>Undefined
              specifies that the identifier property value should be
              used.</para>
            </callout>

            <callout arearefs="version6">
              <para>generated (optional - defaults to
              <literal>never): specifies that this version property
              value is generated by the database. See the discussion of <link
              linkend="mapping-generated">generated properties</link> for more
              information.</para>
            </callout>

            <callout arearefs="version7">
              <para>insert (optional - defaults to
              <literal>true): specifies whether the version column
              should be included in SQL insert statements. It can be set to
              <literal>false if the database column is defined with
              a default value of <literal>0.
            </callout>
          </calloutlist>
        </programlistingco>
      </section>

      <section id="mapping-declaration-timestamp" revision="4">
        <title>Timestamp

        <para>Alternatively, you can use a timestamp. Timestamps are a less
        safe implementation of optimistic locking. However, sometimes an
        application might use the timestamps in other ways as well.</para>

        <para>Simply mark a property of type Date or
        <classname>Calendar as
        <classname>@Version.

        <programlisting language="JAVA" role="JAVA">@Entity
public class Flight implements Serializable {
...
    @Version
    public Date getLastUpdate() { ... }
}           </programlisting>

        <para>When using timestamp versioning you can tell Hibernate where to
        retrieve the timestamp value from - database or JVM - by optionally
        adding the <classname>@org.hibernate.annotations.Source
        annotation to the property. Possible values for the value attribute of
        the annotation are
        <classname>org.hibernate.annotations.SourceType.VM and
        <classname>org.hibernate.annotations.SourceType.DB. The
        default is <classname>SourceType.DB which is also used in
        case there is no <classname>@Source annotation at
        all.</para>

        <para>Like in the case of version numbers, the timestamp can also be
        generated by the database instead of Hibernate. To do that, use
        <code>@org.hibernate.annotations.Generated(GenerationTime.ALWAYS).

        <para>In hbm.xml, use the <timestamp>
        element:</para>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="timestamp1" />

            <area coords="3" id="timestamp2" />

            <area coords="4" id="timestamp3" />

            <area coords="5" id="timestamp4" />

            <area coords="6" id="timestamp5" />

            <area coords="7" id="timestamp6" />
          </areaspec>

          <programlisting><timestamp
        column="timestamp_column"
        name="propertyName"
        access="field|property|ClassName"
        unsaved-value="null|undefined"
        source="vm|db"
        generated="never|always"
        node="element-name|@attribute-name|element/@attribute|."
/></programlisting>

          <calloutlist>
            <callout arearefs="timestamp1">
              <para>column (optional - defaults to the
              property name): the name of a column holding the
              timestamp.</para>
            </callout>

            <callout arearefs="timestamp2">
              <para>name: the name of a JavaBeans style
              property of Java type <literal>Date or
              <literal>Timestamp of the persistent class.
            </callout>

            <callout arearefs="timestamp3">
              <para>access (optional - defaults to
              <literal>property): the strategy Hibernate uses for
              accessing the property value.</para>
            </callout>

            <callout arearefs="timestamp4">
              <para>unsaved-value (optional - defaults to
              <literal>null): a version property value that
              indicates that an instance is newly instantiated (unsaved),
              distinguishing it from detached instances that were saved or
              loaded in a previous session. <literal>Undefined
              specifies that the identifier property value should be
              used.</para>
            </callout>

            <callout arearefs="timestamp5">
              <para>source (optional - defaults to
              <literal>vm): Where should Hibernate retrieve the
              timestamp value from? From the database, or from the current
              JVM? Database-based timestamps incur an overhead because
              Hibernate must hit the database in order to determine the "next
              value". It is safer to use in clustered environments. Not all
              <literal>Dialects are known to support the retrieval
              of the database's current timestamp. Others may also be unsafe
              for usage in locking due to lack of precision (Oracle 8, for
              example).</para>
            </callout>

            <callout arearefs="timestamp6">
              <para>generated (optional - defaults to
              <literal>never): specifies that this timestamp
              property value is actually generated by the database. See the
              discussion of <link linkend="mapping-generated">generated
              properties</link> for more information.
            </callout>
          </calloutlist>
        </programlistingco>

        <note>
          <title>Note

          <para><Timestamp> is equivalent to
          <literal><version type="timestamp">. And
          <literal><timestamp source="db"> is equivalent to
          <literal><version type="dbtimestamp">
        </note>
      </section>
    </section>

    <section id="mapping-declaration-property" revision="4">
      <title>Property

      <para>You need to decide which property needs to be made persistent in a
      given entity. This differs slightly between the annotation driven
      metadata and the hbm.xml files.</para>

      <section>
        <title>Property mapping with annotations

        <para>In the annotations world, every non static non transient
        property (field or method depending on the access type) of an entity
        is considered persistent, unless you annotate it as
        <literal>@Transient. Not having an annotation for your
        property is equivalent to the appropriate <literal>@Basic
        annotation.</para>

        <para>The @Basic annotation allows you to declare
        the fetching strategy for a property. If set to
        <literal>LAZY, specifies that this property should be
        fetched lazily when the instance variable is first accessed. It
        requires build-time bytecode instrumentation, if your classes are not
        instrumented, property level lazy loading is silently ignored. The
        default is <literal>EAGER. You can also mark a property as
        not optional thanks to the <classname>@Basic.optional
        attribute. This will ensure that the underlying column are not
        nullable (if possible). Note that a better approach is to use the
        <classname>@NotNull annotation of the Bean Validation
        specification.</para>

        <para>Let's look at a few examples:

        <programlisting language="JAVA" role="JAVA">public transient int counter; //transient property

private String firstname; //persistent property

@Transient
String getLengthInMeter() { ... } //transient property

String getName() {... } // persistent property

@Basic
int getLength() { ... } // persistent property

@Basic(fetch = FetchType.LAZY)
String getDetailedComment() { ... } // persistent property

@Temporal(TemporalType.TIME)
java.util.Date getDepartureTime() { ... } // persistent property           

@Enumerated(EnumType.STRING)
Starred getNote() { ... } //enum persisted as String in database</programlisting>

        <para>counter, a transient field, and
        <literal>lengthInMeter, a method annotated as
        <literal>@Transient, and will be ignored by the Hibernate.
        <literal>name, length, and
        <literal>firstname properties are mapped persistent and
        eagerly fetched (the default for simple properties). The
        <literal>detailedComment property value will be lazily
        fetched from the database once a lazy property of the entity is
        accessed for the first time. Usually you don't need to lazy simple
        properties (not to be confused with lazy association fetching). The
        recommended alternative is to use the projection capability of JP-QL
        (Java Persistence Query Language) or Criteria queries.</para>

        <para>JPA support property mapping of all basic types supported by
        Hibernate (all basic Java types , their respective wrappers and
        serializable classes). Hibernate Annotations supports out of the box
        enum type mapping either into a ordinal column (saving the enum
        ordinal) or a string based column (saving the enum string
        representation): the persistence representation, defaulted to ordinal,
        can be overridden through the <literal>@Enumerated
        annotation as shown in the <literal>note property
        example.</para>

        <para>In plain Java APIs, the temporal precision of time is not
        defined. When dealing with temporal data you might want to describe
        the expected precision in database. Temporal data can have
        <literal>DATE, TIME, or
        <literal>TIMESTAMP precision (ie the actual date, only the
        time, or both). Use the <literal>@Temporal annotation to
        fine tune that.</para>

        <para>@Lob indicates that the property should be
        persisted in a Blob or a Clob depending on the property type:
        <classname>java.sql.Clob,
        <classname>Character[], char[] and
        java.lang.<classname>String will be persisted in a Clob.
        <classname>java.sql.Blob, Byte[],
        <classname>byte[] and Serializable
        type will be persisted in a Blob.</para>

        <programlisting language="JAVA" role="JAVA">@Lob
public String getFullText() {
    return fullText;
}

@Lob
public byte[] getFullCode() {
    return fullCode;
}</programlisting>

        <para>If the property type implements
        <classname>java.io.Serializable and is not a basic type,
        and if the property is not annotated with <literal>@Lob,
        then the Hibernate <literal>serializable type is
        used.</para>

        <section>
          <title>Type

          <para>You can also manually specify a type using the
          <literal>@org.hibernate.annotations.Type and some
          parameters if needed. <classname>@Type.type could
          be:</para>

          <orderedlist spacing="compact">
            <listitem>
              <para>The name of a Hibernate basic type: integer,
              string, character, date, timestamp, float, binary, serializable,
              object, blob</literal> etc.
            </listitem>

            <listitem>
              <para>The name of a Java class with a default basic type:
              <literal>int, float, char, java.lang.String, java.util.Date,
              java.lang.Integer, java.sql.Clob</literal> etc.
            </listitem>

            <listitem>
              <para>The name of a serializable Java class.
            </listitem>

            <listitem>
              <para>The class name of a custom type:
              <literal>com.illflow.type.MyCustomType etc.
            </listitem>
          </orderedlist>

          <para>If you do not specify a type, Hibernate will use reflection
          upon the named property and guess the correct Hibernate type.
          Hibernate will attempt to interpret the name of the return class of
          the property getter using, in order, rules 2, 3, and 4.</para>

          <para>@org.hibernate.annotations.TypeDef and
          <literal>@org.hibernate.annotations.TypeDefs allows you to
          declare type definitions. These annotations can be placed at the
          class or package level. Note that these definitions are global for
          the session factory (even when defined at the class level). If the
          type is used on a single entity, you can place the definition on the
          entity itself. Otherwise, it is recommended to place the definition
          at the package level. In the example below, when Hibernate
          encounters a property of class <literal>PhoneNumer, it
          delegates the persistence strategy to the custom mapping type
          <literal>PhoneNumberType. However, properties belonging to
          other classes, too, can delegate their persistence strategy to
          <literal>PhoneNumberType, by explicitly using the
          <literal>@Type annotation.

          <note>
            <para>Package level annotations are placed in a file named
            <filename>package-info.java in the appropriate package.
            Place your annotations before the package declaration.</para>
          </note>

          <programlisting language="JAVA" role="JAVA">@TypeDef(
   name = "phoneNumber",
   defaultForType = PhoneNumber.class,
   typeClass = PhoneNumberType.class
)

@Entity
public class ContactDetails {
   [...]
   private PhoneNumber localPhoneNumber;
   @Type(type="phoneNumber")
   private OverseasPhoneNumber overseasPhoneNumber;
   [...]
}</programlisting>

          <para>The following example shows the usage of the
          <literal>parameters attribute to customize the
          TypeDef.</para>

          <programlisting language="JAVA" role="JAVA">//in org/hibernate/test/annotations/entity/package-info.java
@TypeDefs(
    {
    @TypeDef(
        name="caster",
        typeClass = CasterStringType.class,
        parameters = {
            @Parameter(name="cast", value="lower")
        }
    )
    }
)
package org.hibernate.test.annotations.entity;

//in org/hibernate/test/annotations/entity/Forest.java
public class Forest {
    @Type(type="caster")
    public String getSmallText() {
    ...
}      </programlisting>

          <para>When using composite user type, you will have to express
          column definitions. The <literal>@Columns has been
          introduced for that purpose.</para>

          <programlisting language="JAVA" role="JAVA">@Type(type="org.hibernate.test.annotations.entity.MonetaryAmountUserType")
@Columns(columns = {
    @Column(name="r_amount"),
    @Column(name="r_currency")
})
public MonetaryAmount getAmount() {
    return amount;
}


public class MonetaryAmount implements Serializable {
    private BigDecimal amount;
    private Currency currency;
    ...
}</programlisting>
        </section>

        <section>
          <title>Access type

          <para>By default the access type of a class hierarchy is defined by
          the position of the <classname>@Id or
          <classname>@EmbeddedId annotations. If these annotations
          are on a field, then only fields are considered for persistence and
          the state is accessed via the field. If there annotations are on a
          getter, then only the getters are considered for persistence and the
          state is accessed via the getter/setter. That works well in practice
          and is the recommended approach.<note>
              <para>The placement of annotations within a class hierarchy has
              to be consistent (either field or on property) to be able to
              determine the default access type. It is recommended to stick to
              one single annotation placement strategy throughout your whole
              application.</para>
            </note>

          <para>However in some situations, you need to:

          <itemizedlist>
            <listitem>
              <para>force the access type of the entity hierarchy
            </listitem>

            <listitem>
              <para>override the access type of a specific entity in the class
              hierarchy</para>
            </listitem>

            <listitem>
              <para>override the access type of an embeddable type
            </listitem>
          </itemizedlist>

          <para>The best use case is an embeddable class used by several
          entities that might not use the same access type. In this case it is
          better to force the access type at the embeddable class
          level.</para>

          <para>To force the access type on a given class, use the
          <classname>@Access annotation as showed below:

          <programlisting language="JAVA" role="JAVA">@Entity
public class Order {
   @Id private Long id;
   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   @Embedded private Address address;
   public Address getAddress() { return address; }
   public void setAddress() { this.address = address; }
}

@Entity
public class User {
   private Long id;
   @Id public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }

   private Address address;
   @Embedded public Address getAddress() { return address; }
   public void setAddress() { this.address = address; }
}

@Embeddable
@Access(AcessType.PROPERTY)
public class Address {
   private String street1;
   public String getStreet1() { return street1; }
   public void setStreet1() { this.street1 = street1; }

   private hashCode; //not persistent
}</programlisting>

          <para>You can also override the access type of a single property
          while keeping the other properties standard.</para>

          <programlisting language="JAVA" role="JAVA">@Entity
public class Order {
   @Id private Long id;
   public Long getId() { return id; }
   public void setId(Long id) { this.id = id; }
   @Transient private String userId;
   @Transient private String orderId;

   @Access(AccessType.PROPERTY)
   public String getOrderNumber() { return userId + ":" + orderId; }
   public void setOrderNumber() { this.userId = ...; this.orderId = ...; }
}</programlisting>

          <para>In this example, the default access type is
          <classname>FIELD except for the
          <literal>orderNumber property. Note that the corresponding
          field, if any must be marked as <classname>@Transient or
          <code>transient.

          <note>
            <title>@org.hibernate.annotations.AccessType

            <para>The annotation
            <classname>@org.hibernate.annotations.AccessType
            should be considered deprecated for FIELD and PROPERTY access. It
            is still useful however if you need to use a custom access
            type.</para>
          </note>
        </section>

        <section>
          <title>Optimistic lock

          <para>It is sometimes useful to avoid increasing the version number
          even if a given property is dirty (particularly collections). You
          can do that by annotating the property (or collection) with
          <literal>@OptimisticLock(excluded=true).

          <para>More formally, specifies that updates to this property do not
          require acquisition of the optimistic lock.</para>
        </section>

        <section id="entity-mapping-property-column">
          <title>Declaring column attributes

          <para>The column(s) used for a property mapping can be defined using
          the <literal>@Column annotation. Use it to override
          default values (see the JPA specification for more information on
          the defaults). You can use this annotation at the property level for
          properties that are:</para>

          <itemizedlist>
            <listitem>
              <para>not annotated at all
            </listitem>

            <listitem>
              <para>annotated with @Basic
            </listitem>

            <listitem>
              <para>annotated with @Version
            </listitem>

            <listitem>
              <para>annotated with @Lob
            </listitem>

            <listitem>
              <para>annotated with @Temporal
            </listitem>
          </itemizedlist>

          <programlisting language="JAVA" role="JAVA">
@Entity
public class Flight implements Serializable {
...
@Column(updatable = false, name = "flight_name", nullable = false, length=50)
public String getName() { ... }
            </programlisting>

          <para>The name property is mapped to the
          <literal>flight_name column, which is not nullable, has a
          length of 50 and is not updatable (making the property
          immutable).</para>

          <para>This annotation can be applied to regular properties as well
          as <literal>@Id or @Version
          properties.</para>

          <programlistingco>
            <areaspec>
              <area coords="2" id="hm1" />

              <area coords="3" id="hm2" />

              <area coords="4" id="hm3" />

              <area coords="5" id="hm4" />

              <area coords="6" id="hm5" />

              <area coords="7" id="hm6" />

              <area coords="8" id="hm7" />

              <area coords="9" id="hm8" />

              <area coords="10" id="hm9" />

              <area coords="11" id="hm10" />
            </areaspec>

            <programlisting>@Column(
    name="columnName";
    boolean unique() default false;
    boolean nullable() default true;
    boolean insertable() default true;
    boolean updatable() default true;
    String columnDefinition() default "";
    String table() default "";
    int length() default 255;
    int precision() default 0; // decimal precision
    int scale() default 0; // decimal scale</programlisting>

            <calloutlist>
              <callout arearefs="hm1">
                <para>name (optional): the column name
                (default to the property name)</para>
              </callout>

              <callout arearefs="hm2">
                <para>unique (optional): set a unique
                constraint on this column or not (default false)</para>
              </callout>

              <callout arearefs="hm3">
                <para>nullable (optional): set the column
                as nullable (default true).</para>
              </callout>

              <callout arearefs="hm4">
                <para>insertable (optional): whether or not
                the column will be part of the insert statement (default
                true)</para>
              </callout>

              <callout arearefs="hm5">
                <para>updatable (optional): whether or not
                the column will be part of the update statement (default
                true)</para>
              </callout>

              <callout arearefs="hm6">
                <para>columnDefinition (optional): override
                the sql DDL fragment for this particular column (non
                portable)</para>
              </callout>

              <callout arearefs="hm7">
                <para>table (optional): define the targeted
                table (default primary table)</para>
              </callout>

              <callout arearefs="hm8">
                <para>length (optional):
                column length (default 255)</para>
              </callout>

              <callout arearefs="hm8">
                <para>precision
                (optional): column decimal precision (default 0)</para>
              </callout>

              <callout arearefs="hm10">
                <para>scale (optional):
                column decimal scale if useful (default 0)</para>
              </callout>
            </calloutlist>
          </programlistingco>
        </section>

        <section>
          <title>Formula

          <para>Sometimes, you want the Database to do some computation for
          you rather than in the JVM, you might also create some kind of
          virtual column. You can use a SQL fragment (aka formula) instead of
          mapping a property into a column. This kind of property is read only
          (its value is calculated by your formula fragment).</para>

          <programlisting language="JAVA" role="JAVA">@Formula("obj_length * obj_height * obj_width")
public long getObjectVolume()</programlisting>

          <para>The SQL fragment can be as complex as you want and even
          include subselects.</para>
        </section>

        <section>
          <title>Non-annotated property defaults

          <para>If a property is not annotated, the following rules
          apply:<itemizedlist>
              <listitem>
                <para>If the property is of a single type, it is mapped as
                @Basic</para>
              </listitem>

              <listitem>
                <para>Otherwise, if the type of the property is annotated as
                @Embeddable, it is mapped as @Embedded</para>
              </listitem>

              <listitem>
                <para>Otherwise, if the type of the property is
                <classname>Serializable, it is mapped as
                <classname>@Basic in a column holding the object
                in its serialized version</para>
              </listitem>

              <listitem>
                <para>Otherwise, if the type of the property is
                <classname>java.sql.Clob or
                <classname>java.sql.Blob, it is mapped as
                <classname>@Lob with the appropriate
                <classname>LobType
              </listitem>
            </itemizedlist>
        </section>
      </section>

      <section>
        <title>Property mapping with hbm.xml

        <para>The <property> element declares a
        persistent JavaBean style property of the class.</para>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="property1" />

            <area coords="3" id="property2" />

            <area coords="4" id="property3" />

            <areaset coords="" id="property4-5">
              <area coords="5" id="property4" />

              <area coords="6" id="property5" />
            </areaset>

            <area coords="7" id="property6" />

            <area coords="8" id="property7" />

            <area coords="9" id="property8" />

            <area coords="10" id="property9" />

            <area coords="11" id="property10" />

            <area coords="12" id="property11" />

            <area coords="13" id="property12" />
          </areaspec>

          <programlisting><property
        name="propertyName"
        column="column_name"
        type="typename"
        update="true|false"
        insert="true|false"
        formula="arbitrary SQL expression"
        access="field|property|ClassName"
        lazy="true|false"
        unique="true|false"
        not-null="true|false"
        optimistic-lock="true|false"
        generated="never|insert|always"
        node="element-name|@attribute-name|element/@attribute|."
        index="index_name"
        unique_key="unique_key_id"
        length="L"
        precision="P"
        scale="S"
/></programlisting>

          <calloutlist>
            <callout arearefs="property1">
              <para>name: the name of the property, with an
              initial lowercase letter.</para>
            </callout>

            <callout arearefs="property2">
              <para>column (optional - defaults to the
              property name): the name of the mapped database table column.
              This can also be specified by nested
              <literal><column> element(s).
            </callout>

            <callout arearefs="property3">
              <para>type (optional): a name that indicates
              the Hibernate type.</para>
            </callout>

            <callout arearefs="property4-5">
              <para>update, insert (optional - defaults to
              <literal>true): specifies that the mapped columns
              should be included in SQL <literal>UPDATE and/or
              <literal>INSERT statements. Setting both to
              <literal>false allows a pure "derived" property whose
              value is initialized from some other property that maps to the
              same column(s), or by a trigger or other application.</para>
            </callout>

            <callout arearefs="property6">
              <para>formula (optional): an SQL expression
              that defines the value for a <emphasis>computed
              property. Computed properties do not have a column mapping of
              their own.</para>
            </callout>

            <callout arearefs="property7">
              <para>access (optional - defaults to
              <literal>property): the strategy Hibernate uses for
              accessing the property value.</para>
            </callout>

            <callout arearefs="property8">
              <para>lazy (optional - defaults to
              <literal>false): specifies that this property should
              be fetched lazily when the instance variable is first accessed.
              It requires build-time bytecode instrumentation.</para>
            </callout>

            <callout arearefs="property9">
              <para>unique (optional): enables the DDL
              generation of a unique constraint for the columns. Also, allow
              this to be the target of a
              <literal>property-ref.
            </callout>

            <callout arearefs="property10">
              <para>not-null (optional): enables the DDL
              generation of a nullability constraint for the columns.</para>
            </callout>

            <callout arearefs="property11">
              <para>optimistic-lock (optional - defaults to
              <literal>true): specifies that updates to this
              property do or do not require acquisition of the optimistic
              lock. In other words, it determines if a version increment
              should occur when this property is dirty.</para>
            </callout>

            <callout arearefs="property12">
              <para>generated (optional - defaults to
              <literal>never): specifies that this property value is
              actually generated by the database. See the discussion of <link
              linkend="mapping-generated">generated properties</link> for more
              information.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>typename could be:

        <orderedlist spacing="compact">
          <listitem>
            <para>The name of a Hibernate basic type: integer,
            string, character, date, timestamp, float, binary, serializable,
            object, blob</literal> etc.
          </listitem>

          <listitem>
            <para>The name of a Java class with a default basic type:
            <literal>int, float, char, java.lang.String, java.util.Date,
            java.lang.Integer, java.sql.Clob</literal> etc.
          </listitem>

          <listitem>
            <para>The name of a serializable Java class.
          </listitem>

          <listitem>
            <para>The class name of a custom type:
            <literal>com.illflow.type.MyCustomType etc.
          </listitem>
        </orderedlist>

        <para>If you do not specify a type, Hibernate will use reflection upon
        the named property and guess the correct Hibernate type. Hibernate
        will attempt to interpret the name of the return class of the property
        getter using, in order, rules 2, 3, and 4. In certain cases you will
        need the <literal>type attribute. For example, to
        distinguish between <literal>Hibernate.DATE and
        <literal>Hibernate.TIMESTAMP, or to specify a custom
        type.</para>

        <para>The access attribute allows you to control
        how Hibernate accesses the property at runtime. By default, Hibernate
        will call the property get/set pair. If you specify
        <literal>access="field", Hibernate will bypass the get/set
        pair and access the field directly using reflection. You can specify
        your own strategy for property access by naming a class that
        implements the interface
        <literal>org.hibernate.property.PropertyAccessor.

        <para>A powerful feature is derived properties. These properties are
        by definition read-only. The property value is computed at load time.
        You declare the computation as an SQL expression. This then translates
        to a <literal>SELECT clause subquery in the SQL query that
        loads an instance:</para>

        <programlisting role="XML">
<property name="totalPrice"
    formula="( SELECT SUM (li.quantity*p.price) FROM LineItem li, Product p
                WHERE li.productId = p.productId
                AND li.customerId = customerId
                AND li.orderNumber = orderNumber )"/></programlisting>

        <para>You can reference the entity table by not declaring an alias on
        a particular column. This would be <literal>customerId in
        the given example. You can also use the nested
        <literal><formula> mapping element if you do not want
        to use the attribute.</para>
      </section>
    </section>

    <section id="mapping-declaration-component">
      <title>Embedded objects (aka components)

      <para>Embeddable objects (or components) are objects whose properties
      are mapped to the same table as the owning entity's table. Components
      can, in turn, declare their own properties, components or
      collections</para>

      <para>It is possible to declare an embedded component inside an entity
      and even override its column mapping. Component classes have to be
      annotated at the class level with the <literal>@Embeddable
      annotation. It is possible to override the column mapping of an embedded
      object for a particular entity using the <literal>@Embedded
      and <literal>@AttributeOverride annotation in the associated
      property:</para>

      <programlisting language="JAVA" role="JAVA">@Entity
public class Person implements Serializable {

    // Persistent component using defaults
    Address homeAddress;

    @Embedded
    @AttributeOverrides( {
            @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ),
            @AttributeOverride(name="name", column = @Column(name="bornCountryName") )
    } )
    Country bornIn;
    ...
}          </programlisting>

      <programlisting language="JAVA" role="JAVA">@Embeddable
public class Address implements Serializable {
    String city;
    Country nationality; //no overriding here
}            </programlisting>

      <programlisting language="JAVA" role="JAVA">@Embeddable
public class Country implements Serializable {
    private String iso2;
    @Column(name="countryName") private String name;

    public String getIso2() { return iso2; }
    public void setIso2(String iso2) { this.iso2 = iso2; }

    
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    ...
}            </programlisting>

      <para>An embeddable object inherits the access type of its owning entity
      (note that you can override that using the <literal>@Access
      annotation).</para>

      <para>The Person entity has two component properties,
      <literal>homeAddress and bornIn.
      <literal>homeAddress property has not been annotated, but
      Hibernate will guess that it is a persistent component by looking for
      the <literal>@Embeddable annotation in the Address class. We
      also override the mapping of a column name (to
      <literal>bornCountryName) with the
      <literal>@Embedded and @AttributeOverride
      </literal>annotations for each mapped attribute of
      <literal>Country. As you can see, Country
      </literal>is also a nested component of Address,
      again using auto-detection by Hibernate and JPA defaults. Overriding
      columns of embedded objects of embedded objects is through dotted
      expressions.</para>

      <programlisting language="JAVA" role="JAVA">    @Embedded
    @AttributeOverrides( {
            @AttributeOverride(name="city", column = @Column(name="fld_city") ),
            @AttributeOverride(name="nationality.iso2", column = @Column(name="nat_Iso2") ),
            @AttributeOverride(name="nationality.name", column = @Column(name="nat_CountryName") )
            //nationality columns in homeAddress are overridden
    } )
    Address homeAddress;</programlisting>

      <para>Hibernate Annotations supports something that is not explicitly
      supported by the JPA specification. You can annotate a embedded object
      with the <literal>@MappedSuperclass annotation to make the
      superclass properties persistent (see
      <literal>@MappedSuperclass for more informations).

      <para>You can also use association annotations in an embeddable object
      (ie <literal>@OneToOne, @ManyToOne,
      <classname>@OneToMany or @ManyToMany). To
      override the association columns you can use
      <literal>@AssociationOverride.

      <para>If you want to have the same embeddable object type twice in the
      same entity, the column name defaulting will not work as several
      embedded objects would share the same set of columns. In plain JPA, you
      need to override at least one set of columns. Hibernate, however, allows
      you to enhance the default naming mechanism through the
      <classname>NamingStrategy interface. You can write a
      strategy that prevent name clashing in such a situation.
      <classname>DefaultComponentSafeNamingStrategy is an example
      of this.</para>

      <para>If a property of the embedded object points back to the owning
      entity, annotate it with the <classname>@Parent annotation.
      Hibernate will make sure this property is properly loaded with the
      entity reference.</para>

      <para>In XML, use the <component>
      element.</para>

      <programlistingco role="XML">
        <areaspec>
          <area coords="2" id="component1" />

          <area coords="3" id="component2" />

          <area coords="4" id="component3" />

          <area coords="5" id="component4" />

          <area coords="6" id="component5" />

          <area coords="7" id="component6" />

          <area coords="8" id="component7" />

          <area coords="9" id="component8" />
        </areaspec>

        <programlisting><component
        name="propertyName"
        class="className"
        insert="true|false"
        update="true|false"
        access="field|property|ClassName"
        lazy="true|false"
        optimistic-lock="true|false"
        unique="true|false"
        node="element-name|."
>

        <property ...../>
        <many-to-one .... />
        ........
</component></programlisting>

        <calloutlist>
          <callout arearefs="component1">
            <para>name: the name of the property.
          </callout>

          <callout arearefs="component2">
            <para>class (optional - defaults to the
            property type determined by reflection): the name of the component
            (child) class.</para>
          </callout>

          <callout arearefs="component3">
            <para>insert: do the mapped columns appear in
            SQL <literal>INSERTs?
          </callout>

          <callout arearefs="component4">
            <para>update: do the mapped columns appear in
            SQL <literal>UPDATEs?
          </callout>

          <callout arearefs="component5">
            <para>access (optional - defaults to
            <literal>property): the strategy Hibernate uses for
            accessing the property value.</para>
          </callout>

          <callout arearefs="component6">
            <para>lazy (optional - defaults to
            <literal>false): specifies that this component should be
            fetched lazily when the instance variable is first accessed. It
            requires build-time bytecode instrumentation.</para>
          </callout>

          <callout arearefs="component7">
            <para>optimistic-lock (optional - defaults to
            <literal>true): specifies that updates to this component
            either do or do not require acquisition of the optimistic lock. It
            determines if a version increment should occur when this property
            is dirty.</para>
          </callout>

          <callout arearefs="component8">
            <para>unique (optional - defaults to
            <literal>false): specifies that a unique constraint
            exists upon all mapped columns of the component.</para>
          </callout>
        </calloutlist>
      </programlistingco>

      <para>The child <property> tags map properties
      of the child class to table columns.</para>

      <para>The <component> element allows a
      <literal><parent> subelement that maps a property of the
      component class as a reference back to the containing entity.</para>

      <para>The <dynamic-component> element allows a
      <literal>Map to be mapped as a component, where the property
      names refer to keys of the map. See <xref
      linkend="components-dynamic" /> for more information. This feature is
      not supported in annotations.</para>
    </section>

    <section>
      <title>Inheritance strategy

      <para>Java is a language supporting polymorphism: a class can inherit
      from another. Several strategies are possible to persist a class
      hierarchy:</para>

      <itemizedlist>
        <listitem>
          <para>Single table per class hierarchy strategy: a single table
          hosts all the instances of a class hierarchy</para>
        </listitem>

        <listitem>
          <para>Joined subclass strategy: one table per class and subclass is
          present and each table persist the properties specific to a given
          subclass. The state of the entity is then stored in its
          corresponding class table and all its superclasses</para>
        </listitem>

        <listitem>
          <para>Table per class strategy: one table per concrete class and
          subclass is present and each table persist the properties of the
          class and its superclasses. The state of the entity is then stored
          entirely in the dedicated table for its class.</para>
        </listitem>
      </itemizedlist>

      <section id="mapping-declaration-subclass" revision="4">
        <title>Single table per class hierarchy strategy

        <para>With this approach the properties of all the subclasses in a
        given mapped class hierarchy are stored in a single table.</para>

        <para>Each subclass declares its own persistent properties and
        subclasses. Version and id properties are assumed to be inherited from
        the root class. Each subclass in a hierarchy must define a unique
        discriminator value. If this is not specified, the fully qualified
        Java class name is used.</para>

        <programlisting language="JAVA" role="JAVA">@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="planetype",
    discriminatorType=DiscriminatorType.STRING
)
@DiscriminatorValue("Plane")
public class Plane { ... }

@Entity
@DiscriminatorValue("A320")
public class A320 extends Plane { ... }          </programlisting>

        <para>In hbm.xml, for the table-per-class-hierarchy mapping strategy,
        the <literal><subclass> declaration is used. For
        example:</para>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="subclass1" />

            <area coords="3" id="subclass2" />

            <area coords="4" id="subclass3" />

            <area coords="5" id="subclass4" />
          </areaspec>

          <programlisting><subclass
        name="ClassName"
        discriminator-value="discriminator_value"
        proxy="ProxyInterface"
        lazy="true|false"
        dynamic-update="true|false"
        dynamic-insert="true|false"
        entity-name="EntityName"
        node="element-name"
        extends="SuperclassName">

        <property .... />
        .....
</subclass></programlisting>

          <calloutlist>
            <callout arearefs="subclass1">
              <para>name: the fully qualified class name of
              the subclass.</para>
            </callout>

            <callout arearefs="subclass2">
              <para>discriminator-value (optional -
              defaults to the class name): a value that distinguishes
              individual subclasses.</para>
            </callout>

            <callout arearefs="subclass3">
              <para>proxy (optional): specifies a class or
              interface used for lazy initializing proxies.</para>
            </callout>

            <callout arearefs="subclass4">
              <para>lazy (optional - defaults to
              <literal>true): setting
              <literal>lazy="false" disables the use of lazy
              fetching.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>For information about inheritance mappings see 

        <section id="mapping-declaration-discriminator" revision="3">
          <title>Discriminator

          <para>Discriminators are required for polymorphic persistence using
          the table-per-class-hierarchy mapping strategy. It declares a
          discriminator column of the table. The discriminator column contains
          marker values that tell the persistence layer what subclass to
          instantiate for a particular row. Hibernate Core supports the
          follwoing restricted set of types as discriminator column:
          <literal>string, character,
          <literal>integer, byte,
          <literal>short, boolean,
          <literal>yes_no, true_false.

          <para>Use the @DiscriminatorColumn to define
          the discriminator column as well as the discriminator type. <note>
              <para>The enum DiscriminatorType used in
              <classname>javax.persitence.DiscriminatorColumn only
              contains the values <constant>STRING,
              <constant>CHAR and INTEGER which
              means that not all Hibernate supported types are available via
              the <classname>@DiscriminatorColumn
              annotation.</para>
            </note>You can also use
          <classname>@DiscriminatorFormula to express in SQL a
          virtual discriminator column. This is particularly useful when the
          discriminator value can be extracted from one or more columns of the
          table. Both <classname>@DiscriminatorColumn and
          <classname>@DiscriminatorFormula are to be set on the
          root entity (once per persisted hierarchy).</para>

          <para>@org.hibernate.annotations.DiscriminatorOptions
          allows to optionally specify Hibernate specific discriminator
          options which are not standardized in JPA. The available options are
          <literal>force and insert. The
          <literal>force attribute is useful if the table contains
          rows with "extra" discriminator values that are not mapped to a
          persistent class. This could for example occur when working with a
          legacy database. If <literal>force is set to
          <constant>true Hibernate will specify the allowed
          discriminator values in the <literal>SELECT query, even
          when retrieving all instances of the root class. The second option -
          <literal>insert - tells Hibernate whether or not to
          include the discriminator column in SQL <literal>INSERTs.
          Usually the column should be part of the <literal>INSERT
          statement, but if your discriminator column is also part of a mapped
          composite identifier you have to set this option to
          <constant>false.
              <para>There is also a
              <classname>@org.hibernate.annotations.ForceDiscriminator
              annotation which is deprecated since version 3.6. Use
              <classname>@DiscriminatorOptions instead.
            </tip>

          <para>Finally, use @DiscriminatorValue on
          each class of the hierarchy to specify the value stored in the
          discriminator column for a given entity. If you do not set
          <classname>@DiscriminatorValue on a class, the fully
          qualified class name is used.</para>

          <programlisting language="JAVA" role="JAVA">@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="planetype",
    discriminatorType=DiscriminatorType.STRING
)
@DiscriminatorValue("Plane")
public class Plane { ... }

@Entity
@DiscriminatorValue("A320")
public class A320 extends Plane { ... }          </programlisting>

          <para>In hbm.xml, the <discriminator>
          element is used to define the discriminator column or
          formula:</para>

          <programlistingco role="XML">
            <areaspec>
              <area coords="2" id="discriminator1" />

              <area coords="3" id="discriminator2" />

              <area coords="4" id="discriminator3" />

              <area coords="5" id="discriminator4" />

              <area coords="6" id="discriminator5" />
            </areaspec>

            <programlisting><discriminator
        column="discriminator_column"
        type="discriminator_type"
        force="true|false"
        insert="true|false"
        formula="arbitrary sql expression"
/></programlisting>

            <calloutlist>
              <callout arearefs="discriminator1">
                <para>column (optional - defaults to
                <literal>class): the name of the discriminator
                column.</para>
              </callout>

              <callout arearefs="discriminator2">
                <para>type (optional - defaults to
                <literal>string): a name that indicates the
                Hibernate type</para>
              </callout>

              <callout arearefs="discriminator3">
                <para>force (optional - defaults to
                <literal>false): "forces" Hibernate to specify the
                allowed discriminator values, even when retrieving all
                instances of the root class.</para>
              </callout>

              <callout arearefs="discriminator4">
                <para>insert (optional - defaults to
                <literal>true): set this to false
                if your discriminator column is also part of a mapped
                composite identifier. It tells Hibernate not to include the
                column in SQL <literal>INSERTs.
              </callout>

              <callout arearefs="discriminator5">
                <para>formula (optional): an arbitrary SQL
                expression that is executed when a type has to be evaluated.
                It allows content-based discrimination.</para>
              </callout>
            </calloutlist>
          </programlistingco>

          <para>Actual values of the discriminator column are specified by the
          <literal>discriminator-value attribute of the
          <literal><class> and
          <literal><subclass> elements.

          <para>The formula attribute allows you to declare
          an arbitrary SQL expression that will be used to evaluate the type
          of a row. For example:</para>

          <programlisting role="XML"><discriminator
    formula="case when CLASS_TYPE in ('a', 'b', 'c') then 0 else 1 end"
    type="integer"/></programlisting>
        </section>
      </section>

      <section id="mapping-declaration-joinedsubclass" revision="3">
        <title>Joined subclass strategy

        <para>Each subclass can also be mapped to its own table. This is
        called the table-per-subclass mapping strategy. An inherited state is
        retrieved by joining with the table of the superclass. A discriminator
        column is not required for this mapping strategy. Each subclass must,
        however, declare a table column holding the object identifier. The
        primary key of this table is also a foreign key to the superclass
        table and described by the
        <classname>@PrimaryKeyJoinColumns or the
        <literal><key> element.

        <programlisting language="JAVA" role="JAVA">@Entity @Table(name="CATS")
@Inheritance(strategy=InheritanceType.JOINED)
public class Cat implements Serializable { 
    @Id @GeneratedValue(generator="cat-uuid") 
    @GenericGenerator(name="cat-uuid", strategy="uuid")
    String getId() { return id; }

    ...
}

@Entity @Table(name="DOMESTIC_CATS")
@PrimaryKeyJoinColumn(name="CAT")
public class DomesticCat extends Cat { 
    public String getName() { return name; }
}            </programlisting>

        <note>
          <para>The table name still defaults to the non qualified class name.
          Also if <classname>@PrimaryKeyJoinColumn is not set, the
          primary key / foreign key columns are assumed to have the same names
          as the primary key columns of the primary table of the
          superclass.</para>
        </note>

        <para>In hbm.xml, use the <joined-subclass>
        element. For example:</para>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="joinedsubclass1" />

            <area coords="3" id="joinedsubclass2" />

            <area coords="4" id="joinedsubclass3" />

            <area coords="5" id="joinedsubclass4" />
          </areaspec>

          <programlisting><joined-subclass
        name="ClassName"
        table="tablename"
        proxy="ProxyInterface"
        lazy="true|false"
        dynamic-update="true|false"
        dynamic-insert="true|false"
        schema="schema"
        catalog="catalog"
        extends="SuperclassName"
        persister="ClassName"
        subselect="SQL expression"
        entity-name="EntityName"
        node="element-name">

        <key .... >

        <property .... />
        .....
</joined-subclass></programlisting>

          <calloutlist>
            <callout arearefs="joinedsubclass1">
              <para>name: the fully qualified class name of
              the subclass.</para>
            </callout>

            <callout arearefs="joinedsubclass2">
              <para>table: the name of the subclass
              table.</para>
            </callout>

            <callout arearefs="joinedsubclass3">
              <para>proxy (optional): specifies a class or
              interface to use for lazy initializing proxies.</para>
            </callout>

            <callout arearefs="joinedsubclass4">
              <para>lazy (optional, defaults to
              <literal>true): setting
              <literal>lazy="false" disables the use of lazy
              fetching.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>Use the <key> element to declare the
        primary key / foreign key column. The mapping at the start of the
        chapter would then be re-written as:</para>

        <programlisting role="XML"><?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="eg">

        <class name="Cat" table="CATS">
                <id name="id" column="uid" type="long">
                        <generator class="hilo"/>
                </id>
                <property name="birthdate" type="date"/>
                <property name="color" not-null="true"/>
                <property name="sex" not-null="true"/>
                <property name="weight"/>
                <many-to-one name="mate"/>
                <set name="kittens">
                        <key column="MOTHER"/>
                        <one-to-many class="Cat"/>
                </set>
                <joined-subclass name="DomesticCat" table="DOMESTIC_CATS">
                    <key column="CAT"/>
                    <property name="name" type="string"/>
                </joined-subclass>
        </class>

        <class name="eg.Dog">
                <!-- mapping for Dog could go here -->
        </class>

</hibernate-mapping></programlisting>

        <para>For information about inheritance mappings see 
      </section>

      <section id="mapping-declaration-unionsubclass" revision="2">
        <title>Table per class strategy

        <para>A third option is to map only the concrete classes of an
        inheritance hierarchy to tables. This is called the
        table-per-concrete-class strategy. Each table defines all persistent
        states of the class, including the inherited state. In Hibernate, it
        is not necessary to explicitly map such inheritance hierarchies. You
        can map each class as a separate entity root. However, if you wish use
        polymorphic associations (e.g. an association to the superclass of
        your hierarchy), you need to use the union subclass mapping.</para>

        <programlisting language="JAVA" role="JAVA">@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Flight implements Serializable { ... }            </programlisting>

        <para>Or in hbm.xml:

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="unionsubclass1" />

            <area coords="3" id="unionsubclass2" />

            <area coords="4" id="unionsubclass3" />

            <area coords="5" id="unionsubclass4" />
          </areaspec>

          <programlisting><union-subclass
        name="ClassName"
        table="tablename"
        proxy="ProxyInterface"
        lazy="true|false"
        dynamic-update="true|false"
        dynamic-insert="true|false"
        schema="schema"
        catalog="catalog"
        extends="SuperclassName"
        abstract="true|false"
        persister="ClassName"
        subselect="SQL expression"
        entity-name="EntityName"
        node="element-name">

        <property .... />
        .....
</union-subclass></programlisting>

          <calloutlist>
            <callout arearefs="unionsubclass1">
              <para>name: the fully qualified class name of
              the subclass.</para>
            </callout>

            <callout arearefs="unionsubclass2">
              <para>table: the name of the subclass
              table.</para>
            </callout>

            <callout arearefs="unionsubclass3">
              <para>proxy (optional): specifies a class or
              interface to use for lazy initializing proxies.</para>
            </callout>

            <callout arearefs="unionsubclass4">
              <para>lazy (optional, defaults to
              <literal>true): setting
              <literal>lazy="false" disables the use of lazy
              fetching.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>No discriminator column or key column is required for this
        mapping strategy.</para>

        <para>For information about inheritance mappings see 
      </section>

      <section>
        <title>Inherit properties from superclasses

        <para>This is sometimes useful to share common properties through a
        technical or a business superclass without including it as a regular
        mapped entity (ie no specific table for this entity). For that purpose
        you can map them as <literal>@MappedSuperclass.

        <programlisting language="JAVA" role="JAVA">@MappedSuperclass
public class BaseEntity {
    @Basic
    @Temporal(TemporalType.TIMESTAMP)
    public Date getLastUpdate() { ... }
    public String getLastUpdater() { ... }
    ...
}

@Entity class Order extends BaseEntity {
    @Id public Integer getId() { ... }
    ...
}</programlisting>

        <para>In database, this hierarchy will be represented as an
        <literal>Order table having the id,
        <literal>lastUpdate and lastUpdater
        columns. The embedded superclass property mappings are copied into
        their entity subclasses. Remember that the embeddable superclass is
        not the root of the hierarchy though.</para>

        <note>
          <para>Properties from superclasses not mapped as
          <literal>@MappedSuperclass are ignored.
        </note>

        <note>
          <para>The default access type (field or methods) is used, unless you
          use the <literal>@Access annotation.
        </note>

        <note>
          <para>The same notion can be applied to
          <literal>@Embeddable objects to persist properties from
          their superclasses. You also need to use
          <literal>@MappedSuperclass to do that (this should not be
          considered as a standard EJB3 feature though)</para>
        </note>

        <note>
          <para>It is allowed to mark a class as
          <literal>@MappedSuperclass in the middle of the mapped
          inheritance hierarchy.</para>
        </note>

        <note>
          <para>Any class in the hierarchy non annotated with
          <literal>@MappedSuperclass nor @Entity
          will be ignored.</para>
        </note>

        <para>You can override columns defined in entity superclasses at the
        root entity level using the <literal>@AttributeOverride
        annotation.</para>

        <programlisting language="JAVA" role="JAVA">@MappedSuperclass
public class FlyingObject implements Serializable {

    public int getAltitude() {
        return altitude;
    }

    @Transient
    public int getMetricAltitude() {
        return metricAltitude;
    }

    @ManyToOne
    public PropulsionType getPropulsion() {
        return metricAltitude;
    }
    ...
}

@Entity
@AttributeOverride( name="altitude", column = @Column(name="fld_altitude") )
@AssociationOverride( 
   name="propulsion", 
   joinColumns = @JoinColumn(name="fld_propulsion_fk") 
)
public class Plane extends FlyingObject {
    ...
}</programlisting>

        <para>The altitude property will be persisted in an
        <literal>fld_altitude column of table
        <literal>Plane and the propulsion association will be
        materialized in a <literal>fld_propulsion_fk foreign key
        column.</para>

        <para>You can define @AttributeOverride(s) and
        <literal>@AssociationOverride(s) on
        <literal>@Entity classes,
        <literal>@MappedSuperclass classes and properties pointing
        to an <literal>@Embeddable object.

        <para>In hbm.xml, simply map the properties of the superclass in the
        <literal><class> element of the entity that needs to
        inherit them.</para>
      </section>

      <section id="mapping-declaration-join" revision="3">
        <title>Mapping one entity to several tables

        <para>While not recommended for a fresh schema, some legacy databases
        force your to map a single entity on several tables.</para>

        <para>Using the @SecondaryTable or
        <literal>@SecondaryTables class level annotations. To
        express that a column is in a particular table, use the
        <literal>table parameter of @Column or
        <literal>@JoinColumn.

        <programlisting language="JAVA" role="JAVA">@Entity
@Table(name="MainCat")
@SecondaryTables({
    @SecondaryTable(name="Cat1", pkJoinColumns={
        @PrimaryKeyJoinColumn(name="cat_id", referencedColumnName="id")
    ),
    @SecondaryTable(name="Cat2", uniqueConstraints={@UniqueConstraint(columnNames={"storyPart2"})})
})
public class Cat implements Serializable {

    private Integer id;
    private String name;
    private String storyPart1;
    private String storyPart2;

    @Id @GeneratedValue
    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }
    
    @Column(table="Cat1")
    public String getStoryPart1() {
        return storyPart1;
    }

    @Column(table="Cat2")
    public String getStoryPart2() {
        return storyPart2;
    }
}</programlisting>

        <para>In this example, name will be in
        <literal>MainCat. storyPart1 will be in
        <literal>Cat1 and storyPart2 will be in
        <literal>Cat2. Cat1 will be joined to
        <literal>MainCat using the cat_id as a
        foreign key, and <literal>Cat2 using id
        (ie the same column name, the <literal>MainCat id column
        has). Plus a unique constraint on <literal>storyPart2 has
        been set.</para>

        <para>There is also additional tuning accessible via the
        <classname>@org.hibernate.annotations.Table
        annotation:</para>

        <itemizedlist>
          <listitem>
            <para>fetch: If set to JOIN, the default,
            Hibernate will use an inner join to retrieve a secondary table
            defined by a class or its superclasses and an outer join for a
            secondary table defined by a subclass. If set to
            <classname>SELECT then Hibernate will use a sequential
            select for a secondary table defined on a subclass, which will be
            issued only if a row turns out to represent an instance of the
            subclass. Inner joins will still be used to retrieve a secondary
            defined by the class and its superclasses.</para>
          </listitem>

          <listitem>
            <para>inverse: If true, Hibernate will not try
            to insert or update the properties defined by this join. Default
            to false.</para>
          </listitem>

          <listitem>
            <para>optional: If enabled (the default),
            Hibernate will insert a row only if the properties defined by this
            join are non-null and will always use an outer join to retrieve
            the properties.</para>
          </listitem>

          <listitem>
            <para>foreignKey: defines the Foreign Key name
            of a secondary table pointing back to the primary table.</para>
          </listitem>
        </itemizedlist>

        <para>Make sure to use the secondary table name in the
        <methodname>appliesto property

        <programlisting language="JAVA" role="JAVA">@Entity
@Table(name="MainCat")
@SecondaryTable(name="Cat1")
@org.hibernate.annotations.Table(
   appliesTo="Cat1",
   fetch=FetchMode.SELECT,
   optional=true)
public class Cat implements Serializable {

    private Integer id;
    private String name;
    private String storyPart1;
    private String storyPart2;

    @Id @GeneratedValue
    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }
    
    @Column(table="Cat1")
    public String getStoryPart1() {
        return storyPart1;
    }

    @Column(table="Cat2")
    public String getStoryPart2() {
        return storyPart2;
    }
}</programlisting>

        <para>In hbm.xml, use the <join>
        element.</para>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="join1" />

            <area coords="3" id="join2" />

            <area coords="4" id="join3" />

            <area coords="5" id="join4" />

            <area coords="6" id="join5" />

            <area coords="7" id="join6" />
          </areaspec>

          <programlisting><join
        table="tablename"
        schema="owner"
        catalog="catalog"
        fetch="join|select"
        inverse="true|false"
        optional="true|false">

        <key ... />

        <property ... />
        ...
</join></programlisting>

          <calloutlist>
            <callout arearefs="join1">
              <para>table: the name of the joined
              table.</para>
            </callout>

            <callout arearefs="join2">
              <para>schema (optional): overrides the schema
              name specified by the root
              <literal><hibernate-mapping> element.
            </callout>

            <callout arearefs="join3">
              <para>catalog (optional): overrides the
              catalog name specified by the root
              <literal><hibernate-mapping> element.
            </callout>

            <callout arearefs="join4">
              <para>fetch (optional - defaults to
              <literal>join): if set to join, the
              default, Hibernate will use an inner join to retrieve a
              <literal><join> defined by a class or its
              superclasses. It will use an outer join for a
              <literal><join> defined by a subclass. If set to
              <literal>select then Hibernate will use a sequential
              select for a <literal><join> defined on a
              subclass. This will be issued only if a row represents an
              instance of the subclass. Inner joins will still be used to
              retrieve a <literal><join> defined by the class
              and its superclasses.</para>
            </callout>

            <callout arearefs="join5">
              <para>inverse (optional - defaults to
              <literal>false): if enabled, Hibernate will not insert
              or update the properties defined by this join.</para>
            </callout>

            <callout arearefs="join6">
              <para>optional (optional - defaults to
              <literal>false): if enabled, Hibernate will insert a
              row only if the properties defined by this join are non-null. It
              will always use an outer join to retrieve the properties.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>For example, address information for a person can be mapped to a
        separate table while preserving value type semantics for all
        properties:</para>

        <programlisting role="XML"><class name="Person"
    table="PERSON">

    <id name="id" column="PERSON_ID">...</id>

    <join table="ADDRESS">
        <key column="ADDRESS_ID"/>
        <property name="address"/>
        <property name="zip"/>
        <property name="country"/>
    </join>
    ...</programlisting>

        <para>This feature is often only useful for legacy data models. We
        recommend fewer tables than classes and a fine-grained domain model.
        However, it is useful for switching between inheritance mapping
        strategies in a single hierarchy, as explained later.</para>
      </section>
    </section>

    <section>
      <title>Mapping one to one and one to many associations

      <para>To link one entity to an other, you need to map the association
      property as a to one association. In the relational model, you can
      either use a foreign key or an association table, or (a bit less common)
      share the same primary key value between the two entities.</para>

      <para>To mark an association, use either
      <classname>@ManyToOne or
      <classname>@OnetoOne.

      <para>@ManyToOne and @OneToOne
      have a parameter named <literal>targetEntity which describes
      the target entity name. You usually don't need this parameter since the
      default value (the type of the property that stores the association) is
      good in almost all cases. However this is useful when you want to use
      interfaces as the return type instead of the regular entity.</para>

      <para>Setting a value of the cascade attribute to any
      meaningful value other than nothing will propagate certain operations to
      the associated object. The meaningful values are divided into three
      categories.</para>

      <orderedlist>
        <listitem>
          <para>basic operations, which include: persist, merge,
          delete, save-update, evict, replicate, lock and
          refresh</literal>;
        </listitem>

        <listitem>
          <para>special values: delete-orphan or
          <literal>all ;
        </listitem>

        <listitem>
          <para>comma-separated combinations of operation names:
          <literal>cascade="persist,merge,evict" or
          <literal>cascade="all,delete-orphan". See in which case
      Hibernate will proxy the association and load it when the state of the
      associated entity is reached. You can force Hibernate not to use a proxy
      by using <classname>@LazyToOne(NO_PROXY). In this case, the
      property is fetched lazily when the instance variable is first accessed.
      This requires build-time bytecode instrumentation. lazy="false"
      specifies that the association will always be eagerly fetched.</para>

      <para>With the default JPA options, single-ended associations are loaded
      with a subsequent select if set to <literal>LAZY, or a SQL
      JOIN is used for <literal>EAGER associations. You can however
      adjust the fetching strategy, ie how data is fetched by using
      <literal>@Fetch. FetchMode can be
      <literal>SELECT (a select is triggered when the association
      needs to be loaded) or <literal>JOIN (use a SQL JOIN to load
      the association while loading the owner entity). <literal>JOIN
      overrides any lazy attribute (an association loaded through a
      <literal>JOIN strategy cannot be lazy).

      <section id="mapping-declaration-manytoone" revision="5">
        <title>Using a foreign key or an association table

        <para>An ordinary association to another persistent class is declared
        using a</para>

        <itemizedlist>
          <listitem>
            <para>@ManyToOne if several entities can
            point to the the target entity</para>
          </listitem>

          <listitem>
            <para>@OneToOne if only a single entity can
            point to the the target entity</para>
          </listitem>
        </itemizedlist>

        <para>and a foreign key in one table is referencing the primary key
        column(s) of the target table.</para>

        <programlisting language="JAVA" role="JAVA">@Entity
public class Flight implements Serializable {
    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @JoinColumn(name="COMP_ID")
    public Company getCompany() {
        return company;
    }
    ...
}            </programlisting>

        <para>The @JoinColumn attribute is optional, the
        default value(s) is the concatenation of the name of the relationship
        in the owner side, <keycap>_ (underscore), and the name of
        the primary key column in the owned side. In this example
        <literal>company_id because the property name is
        <literal>company and the column id of Company is
        <literal>id.

        <programlisting language="JAVA" role="JAVA">@Entity
public class Flight implements Serializable {
    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE}, targetEntity=CompanyImpl.class )
    @JoinColumn(name="COMP_ID")
    public Company getCompany() {
        return company;
    }
    ...
}

public interface Company {
    ...
}</programlisting>

        <para>You can also map a to one association through an association
        table. This association table described by the
        <literal>@JoinTable annotation will contains a foreign key
        referencing back the entity table (through
        <literal>@JoinTable.joinColumns) and a a foreign key
        referencing the target entity table (through
        <literal>@JoinTable.inverseJoinColumns).

        <programlisting language="JAVA" role="JAVA">@Entity
public class Flight implements Serializable {
    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @JoinTable(name="Flight_Company",
        joinColumns = @JoinColumn(name="FLIGHT_ID"),
        inverseJoinColumns = @JoinColumn(name="COMP_ID")
    )
    public Company getCompany() {
        return company;
    }
    ...
}       </programlisting>

        <note>
          <para>You can use a SQL fragment to simulate a physical join column
          using the <classname>@JoinColumnOrFormula /
          <classname>@JoinColumnOrformulas annotations (just like
          you can use a SQL fragment to simulate a property column via the
          <classname>@Formula annotation).

          <programlisting language="JAVA" role="JAVA">@Entity
public class Ticket implements Serializable {
    @ManyToOne
    @JoinColumnOrFormula(formula="(firstname + ' ' + lastname)")
    public Person getOwner() {
        return person;
    }
    ...
}       </programlisting>
        </note>

        <para>You can mark an association as mandatory by using the
        <literal>optional=false attribute. We recommend to use Bean
        Validation's <classname>@NotNull annotation as a better
        alternative however. As a consequence, the foreign key column(s) will
        be marked as not nullable (if possible).</para>

        <para>When Hibernate cannot resolve the association because the
        expected associated element is not in database (wrong id on the
        association column), an exception is raised. This might be
        inconvenient for legacy and badly maintained schemas. You can ask
        Hibernate to ignore such elements instead of raising an exception
        using the <literal>@NotFound annotation.

        <example>
          <title>@NotFound annotation

          <programlisting language="JAVA" role="JAVA">@Entity
public class Child {
    ...
    @ManyToOne
    @NotFound(action=NotFoundAction.IGNORE)
    public Parent getParent() { ... }
    ...
}</programlisting>
        </example>

        <para>Sometimes you want to delegate to your database the deletion of
        cascade when a given entity is deleted. In this case Hibernate
        generates a cascade delete constraint at the database level.</para>

        <example>
          <title>@OnDelete annotation

          <programlisting language="JAVA" role="JAVA">@Entity
public class Child {
    ...
    @ManyToOne
    @OnDelete(action=OnDeleteAction.CASCADE)
    public Parent getParent() { ... }
    ...
}</programlisting>
        </example>

        <para>Foreign key constraints, while generated by Hibernate, have a
        fairly unreadable name. You can override the constraint name using
        <literal>@ForeignKey.

        <example>
          <title>@ForeignKey annotation

          <programlisting language="JAVA" role="JAVA">@Entity
public class Child {
    ...
    @ManyToOne
    @ForeignKey(name="FK_PARENT")
    public Parent getParent() { ... }
    ...
}

alter table Child add constraint FK_PARENT foreign key (parent_id) references Parent</programlisting>
        </example>

        <para>Sometimes, you want to link one entity to an other not by the
        target entity primary key but by a different unique key. You can
        achieve that by referencing the unique key column(s) in
        <methodname>@JoinColumn.referenceColumnName.

        <programlisting role="JAVA">@Entity
class Person {
   @Id Integer personNumber;
   String firstName;
   @Column(name="I")
   String initial;
   String lastName;
}

@Entity
class Home {
   @ManyToOne
   @JoinColumns({
      @JoinColumn(name="first_name", referencedColumnName="firstName"),
      @JoinColumn(name="init", referencedColumnName="I"),
      @JoinColumn(name="last_name", referencedColumnName="lastName"),
   })
   Person owner
}</programlisting>

        <para>This is not encouraged however and should be reserved to legacy
        mappings.</para>

        <para>In hbm.xml, mapping an association is similar. The main
        difference is that a <classname>@OneToOne is mapped as
        <literal><many-to-one unique="true"/>, let's dive into
        the subject.</para>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="manytoone1" />

            <area coords="3" id="manytoone2" />

            <area coords="4" id="manytoone3" />

            <area coords="5" id="manytoone4" />

            <area coords="6" id="manytoone5" />

            <areaset coords="" id="manytoone6-7">
              <area coords="7" id="manytoone6" />

              <area coords="8" id="manytoone7" />
            </areaset>

            <area coords="9" id="manytoone8" />

            <area coords="10" id="manytoone9" />

            <area coords="11" id="manytoone10" />

            <area coords="12" id="manytoone11" />

            <area coords="13" id="manytoone12" />

            <area coords="14" id="manytoone13" />

            <area coords="15" id="manytoone14" />

            <area coords="16" id="manytoone15" />

            <area coords="17" id="manytoone16" />
          </areaspec>

          <programlisting><many-to-one
        name="propertyName"
        column="column_name"
        class="ClassName"
        cascade="cascade_style"
        fetch="join|select"
        update="true|false"
        insert="true|false"
        property-ref="propertyNameFromAssociatedClass"
        access="field|property|ClassName"
        unique="true|false"
        not-null="true|false"
        optimistic-lock="true|false"
        lazy="proxy|no-proxy|false"
        not-found="ignore|exception"
        entity-name="EntityName"
        formula="arbitrary SQL expression"
        node="element-name|@attribute-name|element/@attribute|."
        embed-xml="true|false"
        index="index_name"
        unique_key="unique_key_id"
        foreign-key="foreign_key_name"
/></programlisting>

          <calloutlist>
            <callout arearefs="manytoone1">
              <para>name: the name of the property.
            </callout>

            <callout arearefs="manytoone2">
              <para>column (optional): the name of the
              foreign key column. This can also be specified by nested
              <literal><column> element(s).
            </callout>

            <callout arearefs="manytoone3">
              <para>class (optional - defaults to the
              property type determined by reflection): the name of the
              associated class.</para>
            </callout>

            <callout arearefs="manytoone4">
              <para>cascade (optional): specifies which
              operations should be cascaded from the parent object to the
              associated object.</para>
            </callout>

            <callout arearefs="manytoone5">
              <para>fetch (optional - defaults to
              <literal>select): chooses between outer-join fetching
              or sequential select fetching.</para>
            </callout>

            <callout arearefs="manytoone6-7">
              <para>update, insert (optional - defaults to
              <literal>true): specifies that the mapped columns
              should be included in SQL <literal>UPDATE and/or
              <literal>INSERT statements. Setting both to
              <literal>false allows a pure "derived" association
              whose value is initialized from another property that maps to
              the same column(s), or by a trigger or other application.</para>
            </callout>

            <callout arearefs="manytoone8">
              <para>property-ref (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>

            <callout arearefs="manytoone9">
              <para>access (optional - defaults to
              <literal>property): the strategy Hibernate uses for
              accessing the property value.</para>
            </callout>

            <callout arearefs="manytoone10">
              <para>unique (optional): enables the DDL
              generation of a unique constraint for the foreign-key column. By
              allowing this to be the target of a
              <literal>property-ref, you can make the association
              multiplicity one-to-one.</para>
            </callout>

            <callout arearefs="manytoone11">
              <para>not-null (optional): enables the DDL
              generation of a nullability constraint for the foreign key
              columns.</para>
            </callout>

            <callout arearefs="manytoone12">
              <para>optimistic-lock (optional - defaults to
              <literal>true): specifies that updates to this
              property do or do not require acquisition of the optimistic
              lock. In other words, it determines if a version increment
              should occur when this property is dirty.</para>
            </callout>

            <callout arearefs="manytoone13">
              <para>lazy (optional - defaults to
              <literal>proxy): by default, single point associations
              are proxied. <literal>lazy="no-proxy" specifies that
              the property should be fetched lazily when the instance variable
              is first accessed. This requires build-time bytecode
              instrumentation. <literal>lazy="false" specifies that
              the association will always be eagerly fetched.</para>
            </callout>

            <callout arearefs="manytoone14">
              <para>not-found (optional - defaults to
              <literal>exception): specifies how foreign keys that
              reference missing rows will be handled.
              <literal>ignore will treat a missing row as a null
              association.</para>
            </callout>

            <callout arearefs="manytoone15">
              <para>entity-name (optional): the entity name
              of the associated class.</para>
            </callout>

            <callout arearefs="manytoone16">
              <para>formula (optional): an SQL expression
              that defines the value for a <emphasis>computed
              foreign key.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>Setting a value of the cascade attribute to
        any meaningful value other than <literal>none will propagate
        certain operations to the associated object. The meaningful values are
        divided into three categories. First, basic operations, which include:
        <literal>persist, merge, delete, save-update, evict, replicate, lock
        and refresh</literal>; second, special values:
        <literal>delete-orphan; and third,all
        comma-separated combinations of operation names:
        <literal>cascade="persist,merge,evict" or
        <literal>cascade="all,delete-orphan". See many-to-one
        declaration:</para>

        <programlisting role="XML"><many-to-one name="product" class="Product" column="PRODUCT_ID"/>

        <para>The property-ref attribute should only be
        used for mapping legacy data where a foreign key refers to a unique
        key of the associated table other than the primary key. This is a
        complicated and confusing relational model. For example, if the
        <literal>Product class had a unique serial number that is
        not the primary key. The <literal>unique attribute controls
        Hibernate's DDL generation with the SchemaExport tool.</para>

        <programlisting role="XML"><property name="serialNumber" unique="true" type="string" column="SERIAL_NUMBER"/>

        <para>Then the mapping for OrderItem might
        use:</para>

        <programlisting role="XML"><many-to-one name="product" property-ref="serialNumber" column="PRODUCT_SERIAL_NUMBER"/>

        <para>This is not encouraged, however.

        <para>If the referenced unique key comprises multiple properties of
        the associated entity, you should map the referenced properties inside
        a named <literal><properties> element.

        <para>If the referenced unique key is the property of a component, you
        can specify a property path:</para>

        <programlisting role="XML"><many-to-one name="owner" property-ref="identity.ssn" column="OWNER_SSN"/>
      </section>

      <section id="mapping-declaration-onetoone" revision="3">
        <title>Sharing the primary key with the associated entity

        <para>The second approach is to ensure an entity and its associated
        entity share the same primary key. In this case the primary key column
        is also a foreign key and there is no extra column. These associations
        are always one to one.</para>

        <example>
          <title>One to One association

          <programlisting language="JAVA" role="JAVA">@Entity
public class Body {
    @Id
    public Long getId() { return id; }

    @OneToOne(cascade = CascadeType.ALL)
    @MapsId
    public Heart getHeart() {
        return heart;
    }
    ...
}   

@Entity
public class Heart {
    @Id
    public Long getId() { ...}
}           </programlisting>
        </example>

        <note>
          <para>Many people got confused by these primary key based one to one
          associations. They can only be lazily loaded if Hibernate knows that
          the other side of the association is always present. To indicate to
          Hibernate that it is the case, use
          <classname>@OneToOne(optional=false).
        </note>

        <para>In hbm.xml, use the following mapping.

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="onetoone1" />

            <area coords="3" id="onetoone2" />

            <area coords="4" id="onetoone3" />

            <area coords="5" id="onetoone4" />

            <area coords="6" id="onetoone5" />

            <area coords="7" id="onetoone6" />

            <area coords="8" id="onetoone7" />

            <area coords="9" id="onetoone8" />

            <area coords="10" id="onetoone9" />

            <area coords="11" id="onetoone10" />
          </areaspec>

          <programlisting><one-to-one
        name="propertyName"
        class="ClassName"
        cascade="cascade_style"
        constrained="true|false"
        fetch="join|select"
        property-ref="propertyNameFromAssociatedClass"
        access="field|property|ClassName"
        formula="any SQL expression"
        lazy="proxy|no-proxy|false"
        entity-name="EntityName"
        node="element-name|@attribute-name|element/@attribute|."
        embed-xml="true|false"
        foreign-key="foreign_key_name"
/></programlisting>

          <calloutlist>
            <callout arearefs="onetoone1">
              <para>name: the name of the property.
            </callout>

            <callout arearefs="onetoone2">
              <para>class (optional - defaults to the
              property type determined by reflection): the name of the
              associated class.</para>
            </callout>

            <callout arearefs="onetoone3">
              <para>cascade (optional): specifies which
              operations should be cascaded from the parent object to the
              associated object.</para>
            </callout>

            <callout arearefs="onetoone4">
              <para>constrained (optional): specifies that
              a foreign key constraint on the primary key of the mapped table
              and references the table of the associated class. This option
              affects the order in which <literal>save() and
              <literal>delete() are cascaded, and determines whether
              the association can be proxied. It is also used by the schema
              export tool.</para>
            </callout>

            <callout arearefs="onetoone5">
              <para>fetch (optional - defaults to
              <literal>select): chooses between outer-join fetching
              or sequential select fetching.</para>
            </callout>

            <callout arearefs="onetoone6">
              <para>property-ref (optional): the name of a
              property of the associated class that is joined to the primary
              key of this class. If not specified, the primary key of the
              associated class is used.</para>
            </callout>

            <callout arearefs="onetoone7">
              <para>access (optional - defaults to
              <literal>property): the strategy Hibernate uses for
              accessing the property value.</para>
            </callout>

            <callout arearefs="onetoone8">
              <para>formula (optional): almost all
              one-to-one associations map to the primary key of the owning
              entity. If this is not the case, you can specify another column,
              columns or expression to join on using an SQL formula. See
              <literal>org.hibernate.test.onetooneformula for an
              example.</para>
            </callout>

            <callout arearefs="onetoone9">
              <para>lazy (optional - defaults to
              <literal>proxy): by default, single point associations
              are proxied. <literal>lazy="no-proxy" specifies that
              the property should be fetched lazily when the instance variable
              is first accessed. It requires build-time bytecode
              instrumentation. <literal>lazy="false" specifies that
              the association will always be eagerly fetched. <emphasis>Note
              that if <literal>constrained="false", proxying is
              impossible and Hibernate will eagerly fetch the
              association</emphasis>.
            </callout>

            <callout arearefs="onetoone10">
              <para>entity-name (optional): the entity name
              of the associated class.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>Primary key associations do not need an extra table column. If
        two rows are related by the association, then the two table rows share
        the same primary key value. To relate two objects by a primary key
        association, ensure that they are assigned the same identifier
        value.</para>

        <para>For a primary key association, add the following mappings to
        <literal>Employee and Person
        respectively:</para>

        <programlisting role="XML"><one-to-one name="person" class="Person"/>

        <programlisting role="XML"><one-to-one name="employee" class="Employee" constrained="true"/>

        <para>Ensure that the primary keys of the related rows in the PERSON
        and EMPLOYEE tables are equal. You use a special Hibernate identifier
        generation strategy called <literal>foreign:

        <programlisting role="XML"><class name="person" table="PERSON">
    <id name="id" column="PERSON_ID">
        <generator class="foreign">
            <param name="property">employee</param>
        </generator>
    </id>
    ...
    <one-to-one name="employee"
        class="Employee"
        constrained="true"/>
</class></programlisting>

        <para>A newly saved instance of Person is assigned
        the same primary key value as the <literal>Employee instance
        referred with the <literal>employee property of that
        <literal>Person.
      </section>
    </section>

    <section id="mapping-declaration-naturalid">
      <title>Natural-id

      <para>Although we recommend the use of surrogate keys as primary keys,
      you should try to identify natural keys for all entities. A natural key
      is a property or combination of properties that is unique and non-null.
      It is also immutable. Map the properties of the natural key as
      <classname>@NaturalId or map them inside the
      <literal><natural-id> element. Hibernate will generate
      the necessary unique key and nullability constraints and, as a result,
      your mapping will be more self-documenting.</para>

      <programlisting language="JAVA" role="JAVA">@Entity
public class Citizen {
    @Id
    @GeneratedValue
    private Integer id;
    private String firstname;
    private String lastname;
    
    @NaturalId
    @ManyToOne
    private State state;

    @NaturalId
    private String ssn;
    ...
}



//and later on query
List results = s.createCriteria( Citizen.class )
                .add( Restrictions.naturalId().set( "ssn", "1234" ).set( "state", ste ) )
                .list();</programlisting>

      <para>Or in XML,

      <programlisting role="XML"><natural-id mutable="true|false"/>
        <property ... />
        <many-to-one ... />
        ......
</natural-id></programlisting>

      <para>It is recommended that you implement equals()
      and <literal>hashCode() to compare the natural key properties
      of the entity.</para>

      <para>This mapping is not intended for use with entities that have
      natural primary keys.</para>

      <itemizedlist spacing="compact">
        <listitem>
          <para>mutable (optional - defaults to
          <literal>false): by default, natural identifier properties
          are assumed to be immutable (constant).</para>
        </listitem>
      </itemizedlist>
    </section>

    <section id="mapping-types-anymapping" revision="2">
      <title>Any

      <para>There is one more type of property mapping. The
      <classname>@Any mapping defines a polymorphic association to
      classes from multiple tables. This type of mapping requires more than
      one column. The first column contains the type of the associated entity.
      The remaining columns contain the identifier. It is impossible to
      specify a foreign key constraint for this kind of association. This is
      not the usual way of mapping polymorphic associations and you should use
      this only in special cases. For example, for audit logs, user session
      data, etc.</para>

      <para>The @Any annotation describes the column
      holding the metadata information. To link the value of the metadata
      information and an actual entity type, The
      <classname>@AnyDef and @AnyDefs
      annotations are used. The <literal>metaType attribute allows
      the application to specify a custom type that maps database column
      values to persistent classes that have identifier properties of the type
      specified by <literal>idType. You must specify the mapping
      from values of the <literal>metaType to class names.

      <programlisting language="JAVA" role="JAVA">@Any( metaColumn = @Column( name = "property_type" ), fetch=FetchType.EAGER )
@AnyMetaDef( 
    idType = "integer", 
    metaType = "string", 
    metaValues = {
        @MetaValue( value = "S", targetEntity = StringProperty.class ),
        @MetaValue( value = "I", targetEntity = IntegerProperty.class )
    } )
@JoinColumn( name = "property_id" )
public Property getMainProperty() {
    return mainProperty;
}</programlisting>

      <para>Note that @AnyDef can be mutualized and
      reused. It is recommended to place it as a package metadata in this
      case.</para>

      <programlisting language="JAVA" role="JAVA">//on a package
@AnyMetaDef( name="property" 
    idType = "integer", 
    metaType = "string", 
    metaValues = {
        @MetaValue( value = "S", targetEntity = StringProperty.class ),
        @MetaValue( value = "I", targetEntity = IntegerProperty.class )
    } )
package org.hibernate.test.annotations.any;


//in a class
    @Any( metaDef="property", metaColumn = @Column( name = "property_type" ), fetch=FetchType.EAGER )
    @JoinColumn( name = "property_id" )
    public Property getMainProperty() {
        return mainProperty;
    }</programlisting>

      <para>The hbm.xml equivalent is:

      <programlisting role="XML"><any name="being" id-type="long" meta-type="string">
    <meta-value value="TBL_ANIMAL" class="Animal"/>
    <meta-value value="TBL_HUMAN" class="Human"/>
    <meta-value value="TBL_ALIEN" class="Alien"/>
    <column name="table_name"/>
    <column name="id"/>
</any></programlisting>

      <note>
        <para>You cannot mutualize the metadata in hbm.xml as you can in
        annotations.</para>
      </note>

      <programlistingco role="XML">
        <areaspec>
          <area coords="2" id="any1" />

          <area coords="3" id="any2" />

          <area coords="4" id="any3" />

          <area coords="5" id="any4" />

          <area coords="6" id="any5" />

          <area coords="7" id="any6" />
        </areaspec>

        <programlisting><any
        name="propertyName"
        id-type="idtypename"
        meta-type="metatypename"
        cascade="cascade_style"
        access="field|property|ClassName"
        optimistic-lock="true|false"
>
        <meta-value ... />
        <meta-value ... />
        .....
        <column .... />
        <column .... />
        .....
</any></programlisting>

        <calloutlist>
          <callout arearefs="any1">
            <para>name: the property name.
          </callout>

          <callout arearefs="any2">
            <para>id-type: the identifier type.
          </callout>

          <callout arearefs="any3">
            <para>meta-type (optional - defaults to
            <literal>string): any type that is allowed for a
            discriminator mapping.</para>
          </callout>

          <callout arearefs="any4">
            <para>cascade (optional- defaults to
            <literal>none): the cascade style.
          </callout>

          <callout arearefs="any5">
            <para>access (optional - defaults to
            <literal>property): the strategy Hibernate uses for
            accessing the property value.</para>
          </callout>

          <callout arearefs="any6">
            <para>optimistic-lock (optional - defaults to
            <literal>true): specifies that updates to this property
            either do or do not require acquisition of the optimistic lock. It
            defines whether a version increment should occur if this property
            is dirty.</para>
          </callout>
        </calloutlist>
      </programlistingco>
    </section>

    <section id="mapping-declaration-properties" revision="2">
      <title>Properties

      <para>The <properties> element allows the
      definition of a named, logical grouping of the properties of a class.
      The most important use of the construct is that it allows a combination
      of properties to be the target of a <literal>property-ref. It
      is also a convenient way to define a multi-column unique constraint. For
      example:</para>

      <programlistingco role="XML">
        <areaspec>
          <area coords="2" id="properties1" />

          <area coords="3" id="properties2" />

          <area coords="4" id="properties3" />

          <area coords="5" id="properties4" />

          <area coords="6" id="properties5" />
        </areaspec>

        <programlisting><properties
        name="logicalName"
        insert="true|false"
        update="true|false"
        optimistic-lock="true|false"
        unique="true|false"
>

        <property ...../>
        <many-to-one .... />
        ........
</properties></programlisting>

        <calloutlist>
          <callout arearefs="properties1">
            <para>name: the logical name of the grouping.
            It is <emphasis>not an actual property name.
          </callout>

          <callout arearefs="properties2">
            <para>insert: do the mapped columns appear in
            SQL <literal>INSERTs?
          </callout>

          <callout arearefs="properties3">
            <para>update: do the mapped columns appear in
            SQL <literal>UPDATEs?
          </callout>

          <callout arearefs="properties4">
            <para>optimistic-lock (optional - defaults to
            <literal>true): specifies that updates to these
            properties either do or do not require acquisition of the
            optimistic lock. It determines if a version increment should occur
            when these properties are dirty.</para>
          </callout>

          <callout arearefs="properties5">
            <para>unique (optional - defaults to
            <literal>false): specifies that a unique constraint
            exists upon all mapped columns of the component.</para>
          </callout>
        </calloutlist>
      </programlistingco>

      <para>For example, if we have the following
      <literal><properties> mapping:

      <programlisting role="XML"><class name="Person">
    <id name="personNumber"/>

    ...
    <properties name="name"
            unique="true" update="false">
        <property name="firstName"/>
        <property name="initial"/>
        <property name="lastName"/>
    </properties>
</class></programlisting>

      <para>You might have some legacy data association that refers to this
      unique key of the <literal>Person table, instead of to the
      primary key:</para>

      <programlisting role="XML"><many-to-one name="owner"
         class="Person" property-ref="name">
    <column name="firstName"/>
    <column name="initial"/>
    <column name="lastName"/>
</many-to-one></programlisting>

      <note>
        <para>When using annotations as a mapping strategy, such construct is
        not necessary as the binding between a column and its related column
        on the associated table is done directly</para>

        <programlisting role="JAVA">@Entity
class Person {
   @Id Integer personNumber;
   String firstName;
   @Column(name="I")
   String initial;
   String lastName;
}

@Entity
class Home {
   @ManyToOne
   @JoinColumns({
      @JoinColumn(name="first_name", referencedColumnName="firstName"),
      @JoinColumn(name="init", referencedColumnName="I"),
      @JoinColumn(name="last_name", referencedColumnName="lastName"),
   })
   Person owner
}</programlisting>
      </note>

      <para>The use of this outside the context of mapping legacy data is not
      recommended.</para>
    </section>

    <section>
      <title>Some hbm.xml specificities

      <para>The hbm.xml structure has some specificities naturally not present
      when using annotations, let's describe them briefly.</para>

      <section id="mapping-declaration-doctype" revision="3">
        <title>Doctype

        <para>All XML mappings should declare the doctype shown. The actual
        DTD can be found at the URL above, in the directory
        <literal>hibernate-x.x.x/src/org/hibernate , or in
        <literal>hibernate3.jar. Hibernate will always look for the
        DTD in its classpath first. If you experience lookups of the DTD using
        an Internet connection, check the DTD declaration against the contents
        of your classpath.</para>

        <section id="mapping-declaration-entity-resolution">
          <title>EntityResolver

          <para>Hibernate will first attempt to resolve DTDs in its classpath.
          It does this is by registering a custom
          <literal>org.xml.sax.EntityResolver implementation with
          the SAXReader it uses to read in the xml files. This custom
          <literal>EntityResolver recognizes two different systemId
          namespaces:</para>

          <itemizedlist>
            <listitem>
              <para>a hibernate namespace is recognized
              whenever the resolver encounters a systemId starting with
              <literal>http://www.hibernate.org/dtd/. The resolver
              attempts to resolve these entities via the classloader which
              loaded the Hibernate classes.</para>
            </listitem>

            <listitem>
              <para>a user namespace is recognized whenever
              the resolver encounters a systemId using a
              <literal>classpath:// URL protocol. The resolver will
              attempt to resolve these entities via (1) the current thread
              context classloader and (2) the classloader which loaded the
              Hibernate classes.</para>
            </listitem>
          </itemizedlist>

          <para>The following is an example of utilizing user
          namespacing:</para>

          <programlisting language="XML" role="XML">
<xi:include href="../extras/namespacing.xml_sample" parse="text"
              xmlns:xi="http://www.w3.org/2001/XInclude" />
</programlisting>

          <para>Where types.xml is a resource in the
          <literal>your.domain package and contains a custom .
        </section>
      </section>

      <section id="mapping-declaration-mapping" revision="3">
        <title>Hibernate-mapping

        <para>This element has several optional attributes. The
        <literal>schema and catalog attributes
        specify that tables referred to in this mapping belong to the named
        schema and/or catalog. If they are specified, tablenames will be
        qualified by the given schema and catalog names. If they are missing,
        tablenames will be unqualified. The <literal>default-cascade
        attribute specifies what cascade style should be assumed for
        properties and collections that do not specify a
        <literal>cascade attribute. By default, the
        <literal>auto-import attribute allows you to use unqualified
        class names in the query language.</para>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="hm1" />

            <area coords="3" id="hm2" />

            <area coords="4" id="hm3" />

            <area coords="5" id="hm4" />

            <area coords="6" id="hm5" />

            <area coords="7" id="hm6" />

            <area coords="8" id="hm7" />
          </areaspec>

          <programlisting><hibernate-mapping
         schema="schemaName"
         catalog="catalogName"
         default-cascade="cascade_style"
         default-access="field|property|ClassName"
         default-lazy="true|false"
         auto-import="true|false"
         package="package.name"
 /></programlisting>

          <calloutlist>
            <callout arearefs="hm1">
              <para>schema (optional): the name of a
              database schema.</para>
            </callout>

            <callout arearefs="hm2">
              <para>catalog (optional): the name of a
              database catalog.</para>
            </callout>

            <callout arearefs="hm3">
              <para>default-cascade (optional - defaults to
              <literal>none): a default cascade style.
            </callout>

            <callout arearefs="hm4">
              <para>default-access (optional - defaults to
              <literal>property): the strategy Hibernate should use
              for accessing all properties. It can be a custom implementation
              of <literal>PropertyAccessor.
            </callout>

            <callout arearefs="hm5">
              <para>default-lazy (optional - defaults to
              <literal>true): the default value for unspecified
              <literal>lazy attributes of class and collection
              mappings.</para>
            </callout>

            <callout arearefs="hm6">
              <para>auto-import (optional - defaults to
              <literal>true): specifies whether we can use
              unqualified class names of classes in this mapping in the query
              language.</para>
            </callout>

            <callout arearefs="hm7">
              <para>package (optional): specifies a package
              prefix to use for unqualified class names in the mapping
              document.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>If you have two persistent classes with the same unqualified
        name, you should set <literal>auto-import="false". An
        exception will result if you attempt to assign two classes to the same
        "imported" name.</para>

        <para>The hibernate-mapping element allows you to
        nest several persistent <literal><class> mappings, as
        shown above. It is, however, good practice (and expected by some
        tools) to map only a single persistent class, or a single class
        hierarchy, in one mapping file and name it after the persistent
        superclass. For example, <literal>Cat.hbm.xml,
        <literal>Dog.hbm.xml, or if using inheritance,
        <literal>Animal.hbm.xml.
      </section>

      <section id="mapping-declaration-key">
        <title id="section.key">Key

        <para>The <key> element is featured a few
        times within this guide. It appears anywhere the parent mapping
        element defines a join to a new table that references the primary key
        of the original table. It also defines the foreign key in the joined
        table:</para>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="key1" />

            <area coords="3" id="key2" />

            <area coords="4" id="key3" />

            <area coords="5" id="key4" />

            <area coords="6" id="key5" />

            <area coords="7" id="key6" />
          </areaspec>

          <programlisting><key
        column="columnname"
        on-delete="noaction|cascade"
        property-ref="propertyName"
        not-null="true|false"
        update="true|false"
        unique="true|false"
/></programlisting>

          <calloutlist>
            <callout arearefs="key1">
              <para>column (optional): the name of the
              foreign key column. This can also be specified by nested
              <literal><column> element(s).
            </callout>

            <callout arearefs="key2">
              <para>on-delete (optional - defaults to
              <literal>noaction): specifies whether the foreign key
              constraint has database-level cascade delete enabled.</para>
            </callout>

            <callout arearefs="key3">
              <para>property-ref (optional): specifies that
              the foreign key refers to columns that are not the primary key
              of the original table. It is provided for legacy data.</para>
            </callout>

            <callout arearefs="key4">
              <para>not-null (optional): specifies that the
              foreign key columns are not nullable. This is implied whenever
              the foreign key is also part of the primary key.</para>
            </callout>

            <callout arearefs="key5">
              <para>update (optional): specifies that the
              foreign key should never be updated. This is implied whenever
              the foreign key is also part of the primary key.</para>
            </callout>

            <callout arearefs="key6">
              <para>unique (optional): specifies that the
              foreign key should have a unique constraint. This is implied
              whenever the foreign key is also the primary key.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <para>For systems where delete performance is important, we recommend
        that all keys should be defined
        <literal>on-delete="cascade". Hibernate uses a
        database-level <literal>ON CASCADE DELETE constraint,
        instead of many individual <literal>DELETE statements. Be
        aware that this feature bypasses Hibernate's usual optimistic locking
        strategy for versioned data.</para>

        <para>The not-null and update
        attributes are useful when mapping a unidirectional one-to-many
        association. If you map a unidirectional one-to-many association to a
        non-nullable foreign key, you <emphasis>must declare the
        key column using <literal><key
        not-null="true"></literal>.
      </section>

      <section id="mapping-declaration-import">
        <title>Import

        <para>If your application has two persistent classes with the same
        name, and you do not want to specify the fully qualified package name
        in Hibernate queries, classes can be "imported" explicitly, rather
        than relying upon <literal>auto-import="true". You can also
        import classes and interfaces that are not explicitly mapped:</para>

        <programlisting role="XML"><import class="java.lang.Object" rename="Universe"/>

        <programlistingco role="XML">
          <areaspec>
            <area coords="2" id="import1" />

            <area coords="3" id="import2" />
          </areaspec>

          <programlisting><import
        class="ClassName"
        rename="ShortName"
/></programlisting>

          <calloutlist>
            <callout arearefs="import1">
              <para>class: the fully qualified class name
              of any Java class.</para>
            </callout>

            <callout arearefs="import2">
              <para>rename (optional - defaults to the
              unqualified class name): a name that can be used in the query
              language.</para>
            </callout>
          </calloutlist>
        </programlistingco>

        <note>
          <para>This feature is unique to hbm.xml and is not supported in
          annotations.</para>
        </note>
      </section>

      <section id="mapping-column" revision="5">
        <title>Column and formula elements

        <para>Mapping elements which accept a column
        attribute will alternatively accept a
        <literal><column> subelement. Likewise,
        <literal><formula> is an alternative to the
        <literal>formula attribute. For example:

        <programlisting role="XML"><column
        name="column_name"
        length="N"
        precision="N"
        scale="N"
        not-null="true|false"
        unique="true|false"
        unique-key="multicolumn_unique_key_name"
        index="index_name"
        sql-type="sql_type_name"
        check="SQL expression"
        default="SQL expression"
        read="SQL expression"
        write="SQL expression"/></programlisting>

        <programlisting role="XML"><formula>SQL expression</formula>

        <para>Most of the attributes on column provide a
        means of tailoring the DDL during automatic schema generation. The
        <literal>read and write attributes allow
        you to specify custom SQL that Hibernate will use to access the
        column's value. For more on this, see the discussion of <link
        linkend="mapping-column-read-and-write">column read and write
        expressions</link>.

        <para>The column and formula
        elements can even be combined within the same property or association
        mapping to express, for example, exotic join conditions.</para>

        <programlisting role="XML"><many-to-one name="homeAddress" class="Address"
        insert="false" update="false">
    <column name="person_id" not-null="true" length="10"/>
    <formula>'MAILING'</formula>
</many-to-one></programlisting>
      </section>
    </section>
  </section>

  <section id="mapping-types">
    <title>Hibernate types

    <section id="mapping-types-entitiesvalues" revision="1">
      <title>Entities and values

      <para>In relation to the persistence service, Java language-level
      objects are classified into two groups:</para>

      <para>An entity exists independently of any other
      objects holding references to the entity. Contrast this with the usual
      Java model, where an unreferenced object is garbage collected. Entities
      must be explicitly saved and deleted. Saves and deletions, however, can
      be <emphasis>cascaded from a parent entity to its children.
      This is different from the ODMG model of object persistence by
      reachability and corresponds more closely to how application objects are
      usually used in large systems. Entities support circular and shared
      references. They can also be versioned.</para>

      <para>An entity's persistent state consists of references to other
      entities and instances of <emphasis>value types. Values are
      primitives: collections (not what is inside a collection), components
      and certain immutable objects. Unlike entities, values in particular
      collections and components, <emphasis>are persisted and
      deleted by reachability. Since value objects and primitives are
      persisted and deleted along with their containing entity, they cannot be
      independently versioned. Values have no independent identity, so they
      cannot be shared by two entities or collections.</para>

      <para>Until now, we have been using the term "persistent class" to refer
      to entities. We will continue to do that. Not all user-defined classes
      with a persistent state, however, are entities. A
      <emphasis>component is a user-defined class with value
      semantics. A Java property of type <literal>java.lang.String
      also has value semantics. Given this definition, all types (classes)
      provided by the JDK have value type semantics in Java, while
      user-defined types can be mapped with entity or value type semantics.
      This decision is up to the application developer. An entity class in a
      domain model will normally have shared references to a single instance
      of that class, while composition or aggregation usually translates to a
      value type.</para>

      <para>We will revisit both concepts throughout this reference
      guide.</para>

      <para>The challenge is to map the Java type system, and the developers'
      definition of entities and value types, to the SQL/database type system.
      The bridge between both systems is provided by Hibernate. For entities,
      <literal><class>, <subclass>
      and so on are used. For value types we use
      <literal><property>,
      <literal><component>etc., that usually have a
      <literal>type attribute. The value of this attribute is the
      name of a Hibernate <emphasis>mapping type. Hibernate
      provides a range of mappings for standard JDK value types out of the
      box. You can write your own mapping types and implement your own custom
      conversion strategies.</para>

      <para>With the exception of collections, all built-in Hibernate types
      support null semantics.</para>
    </section>

    <section id="mapping-types-basictypes" revision="4">
      <title>Basic value types

      <para>The built-in basic mapping types can be
      roughly categorized into the following: <variablelist>
          <varlistentry>
            <term>integer, long, short, float, double, character,
            byte, boolean, yes_no, true_false</literal>

            <listitem>
              <para>Type mappings from Java primitives or wrapper classes to
              appropriate (vendor-specific) SQL column types.
              <literal>boolean, yes_no and
              <literal>true_false are all alternative encodings for
              a Java <literal>boolean or
              <literal>java.lang.Boolean.
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>string

            <listitem>
              <para>A type mapping from java.lang.String to
              <literal>VARCHAR (or Oracle
              <literal>VARCHAR2).
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>date, time, timestamp

            <listitem>
              <para>Type mappings from java.util.Date and
              its subclasses to SQL types <literal>DATE,
              <literal>TIME and TIMESTAMP (or
              equivalent).</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>calendar, calendar_date

            <listitem>
              <para>Type mappings from java.util.Calendar
              to SQL types <literal>TIMESTAMP and
              <literal>DATE (or equivalent).
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>big_decimal, big_integer

            <listitem>
              <para>Type mappings from java.math.BigDecimal
              and <literal>java.math.BigInteger to
              <literal>NUMERIC (or Oracle
              <literal>NUMBER).
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>locale, timezone, currency

            <listitem>
              <para>Type mappings from java.util.Locale,
              <literal>java.util.TimeZone and
              <literal>java.util.Currency to
              <literal>VARCHAR (or Oracle
              <literal>VARCHAR2). Instances of
              <literal>Locale and Currency are
              mapped to their ISO codes. Instances of
              <literal>TimeZone are mapped to their
              <literal>ID.
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>class

            <listitem>
              <para>A type mapping from java.lang.Class to
              <literal>VARCHAR (or Oracle
              <literal>VARCHAR2). A Class is
              mapped to its fully qualified name.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>binary

            <listitem>
              <para>Maps byte arrays to an appropriate SQL binary type.
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>text

            <listitem>
              <para>Maps long Java strings to a SQL LONGVARCHAR or
              <literal>TEXT type.
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>image

            <listitem>
              <para>Maps long byte arrays to a SQL LONGVARBINARY.
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>serializable

            <listitem>
              <para>Maps serializable Java types to an appropriate SQL binary
              type. You can also indicate the Hibernate type
              <literal>serializable with the name of a serializable
              Java class or interface that does not default to a basic
              type.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>clob, blob

            <listitem>
              <para>Type mappings for the JDBC classes
              <literal>java.sql.Clob and
              <literal>java.sql.Blob. These types can be
              inconvenient for some applications, since the blob or clob
              object cannot be reused outside of a transaction. Driver support
              is patchy and inconsistent.</para>
            </listitem>
          </varlistentry>

           <varlistentry>
            <term>materialized_clob

            <listitem>
              <para>Maps long Java strings to a SQL CLOB 
              type. When read, the <literal>CLOB value is
              immediately materialized into a Java string. Some drivers 
              require the <literal>CLOB value to be read within
              a transaction. Once materialized, the Java string is 
              available outside of the transaction.</para>
            </listitem>
          </varlistentry>

           <varlistentry>
            <term>materialized_blob

            <listitem>
              <para>Maps long Java byte arrays to a SQL BLOB 
              type. When read, the <literal>BLOB value is
              immediately materialized into a byte array. Some drivers 
              require the <literal>BLOB value to be read within
              a transaction. Once materialized, the byte array is 
              available outside of the transaction.</para>
            </listitem>
          </varlistentry>

          <varlistentry>
            <term>imm_date, imm_time, imm_timestamp, imm_calendar,
            imm_calendar_date, imm_serializable, imm_binary</literal>

            <listitem>
              <para>Type mappings for what are considered mutable Java types.
              This is where Hibernate makes certain optimizations appropriate
              only for immutable Java types, and the application treats the
              object as immutable. For example, you should not call
              <literal>Date.setTime() for an instance mapped as
              <literal>imm_timestamp. To change the value of the
              property, and have that change made persistent, the application
              must assign a new, nonidentical, object to the property.</para>
            </listitem>
          </varlistentry>
        </variablelist>

      <para>Unique identifiers of entities and collections can be of any basic
      type except <literal>binary, blob and
      <literal>clob. Composite identifiers are also allowed. See
      below for more information.</para>

      <para>The basic value types have corresponding Type
      constants defined on <literal>org.hibernate.Hibernate. For
      example, <literal>Hibernate.STRING represents the
      <literal>string type.
    </section>

    <section id="mapping-types-custom" revision="2">
      <title>Custom value types

      <para>It is relatively easy for developers to create their own value
      types. For example, you might want to persist properties of type
      <literal>java.lang.BigInteger to VARCHAR
      columns. Hibernate does not provide a built-in type for this. Custom
      types are not limited to mapping a property, or collection element, to a
      single table column. So, for example, you might have a Java property
      <literal>getName()/setName() of type
      <literal>java.lang.String that is persisted to the columns
      <literal>FIRST_NAME, INITIAL,
      <literal>SURNAME.

      <para>To implement a custom type, implement either
      <literal>org.hibernate.UserType or
      <literal>org.hibernate.CompositeUserType and declare
      properties using the fully qualified classname of the type. View
      <literal>org.hibernate.test.DoubleStringType to see the kind
      of things that are possible.</para>

      <programlisting role="XML"><property name="twoStrings" type="org.hibernate.test.DoubleStringType">
    <column name="first_string"/>
    <column name="second_string"/>
</property></programlisting>

      <para>Notice the use of <column> tags to map a
      property to multiple columns.</para>

      <para>The CompositeUserType,
      <literal>EnhancedUserType,
      <literal>UserCollectionType, and
      <literal>UserVersionType interfaces provide support for more
      specialized uses.</para>

      <para>You can even supply parameters to a UserType in
      the mapping file. To do this, your <literal>UserType must
      implement the
      <literal>org.hibernate.usertype.ParameterizedType interface.
      To supply parameters to your custom type, you can use the
      <literal><type> element in your mapping files.

      <programlisting role="XML"><property name="priority">
    <type name="com.mycompany.usertypes.DefaultValueIntegerType">
        <param name="default">0</param>
    </type>
</property></programlisting>

      <para>The UserType can now retrieve the value for the
      parameter named <literal>default from the
      <literal>Properties object passed to it.

      <para>If you regularly use a certain UserType, it is
      useful to define a shorter name for it. You can do this using the
      <literal><typedef> element. Typedefs assign a name to a
      custom type, and can also contain a list of default parameter values if
      the type is parameterized.</para>

      <programlisting role="XML"><typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
    <param name="default">0</param>
</typedef></programlisting>

      <programlisting role="XML"><property name="priority" type="default_zero"/>

      <para>It is also possible to override the parameters supplied in a
      typedef on a case-by-case basis by using type parameters on the property
      mapping.</para>

      <para>Even though Hibernate's rich range of built-in types and support
      for components means you will rarely need to use a custom type, it is
      considered good practice to use custom types for non-entity classes that
      occur frequently in your application. For example, a
      <literal>MonetaryAmount class is a good candidate for a
      <literal>CompositeUserType, even though it could be mapped as
      a component. One reason for this is abstraction. With a custom type,
      your mapping documents would be protected against changes to the way
      monetary values are represented.</para>
    </section>
  </section>

  <section id="mapping-entityname">
    <title>Mapping a class more than once

    <para>It is possible to provide more than one mapping for a particular
    persistent class. In this case, you must specify an <emphasis>entity
    name</emphasis> to disambiguate between instances of the two mapped
    entities. By default, the entity name is the same as the class name.
    Hibernate lets you specify the entity name when working with persistent
    objects, when writing queries, or when mapping associations to the named
    entity.</para>

    <programlisting><class name="Contract" table="Contracts"
        entity-name="CurrentContract">
    ...
    <set name="history" inverse="true"
            order-by="effectiveEndDate desc">
        <key column="currentContractId"/>
        <one-to-many entity-name="HistoricalContract"/>
    </set>
</class>

<class name="Contract" table="ContractHistory"
        entity-name="HistoricalContract">
    ...
    <many-to-one name="currentContract"
            column="currentContractId"
            entity-name="CurrentContract"/>
</class></programlisting>

    <para>Associations are now specified using entity-name
    instead of <literal>class.

    <note>
      <para>This feature is not supported in Annotations
    </note>
  </section>

  <section id="mapping-quotedidentifiers">
    <title>SQL quoted identifiers

    <para>You can force Hibernate to quote an identifier in the generated SQL
    by enclosing the table or column name in backticks in the mapping
    document. Hibernate will use the correct quotation style for the SQL
    <literal>Dialect. This is usually double quotes, but the SQL
    Server uses brackets and MySQL uses backticks.</para>

    <programlisting role="XML">@Entity @Table(name="`Line Item`")
class LineItem {
   @id @Column(name="`Item Id`") Integer id;
   @Column(name="`Item #`") int itemNumber
}

<class name="LineItem" table="`Line Item`">
    <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
    <property name="itemNumber" column="`Item #`"/>
    ...
</class></programlisting>
  </section>

  <section id="mapping-generated" revision="1">
    <title>Generated properties

    <para>Generated properties are properties that have their values generated
    by the database. Typically, Hibernate applications needed to
    <literal>refresh objects that contain any properties for which
    the database was generating values. Marking properties as generated,
    however, lets the application delegate this responsibility to Hibernate.
    When Hibernate issues an SQL INSERT or UPDATE for an entity that has
    defined generated properties, it immediately issues a select afterwards to
    retrieve the generated values.</para>

    <para>Properties marked as generated must additionally be non-insertable
    and non-updateable. Only <link
    linkend="mapping-declaration-version">versions</link>, , and , can be
    marked as generated.</para>

    <para>never (the default): the given property value is
    not generated within the database.</para>

    <para>insert: the given property value is generated on
    insert, but is not regenerated on subsequent updates. Properties like
    created-date fall into this category. Even though <link
    linkend="mapping-declaration-version">version</link> and  properties can be
    marked as generated, this option is not available.</para>

    <para>always: the property value is generated both on
    insert and on update.</para>

    <para>To mark a property as generated, use
    <classname>@Generated.
  </section>

  <section id="mapping-column-read-and-write" revision="1">
    <title>Column transformers: read and write expressions

    <para>Hibernate allows you to customize the SQL it uses to read and write
    the values of columns mapped to <link
    linkend="mapping-declaration-property">simple properties</link>. For
    example, if your database provides a set of data encryption functions, you
    can invoke them for individual columns like this:</para>

    <programlisting role="JAVA">@Entity
class CreditCard {
   @Column(name="credit_card_num")
   @ColumnTransformer(
      read="decrypt(credit_card_num)", 
      write="encrypt(?)")
   public String getCreditCardNumber() { return creditCardNumber; }
   public void setCreditCardNumber(String number) { this.creditCardNumber = number; }
   private String creditCardNumber;
}</programlisting>

    <para>or in XML

    <programlisting role="XML"><property name="creditCardNumber">
        <column 
          name="credit_card_num"
          read="decrypt(credit_card_num)"
          write="encrypt(?)"/>
</property></programlisting>

    <note>
      <para>You can use the plural form
      <classname>@ColumnTransformers if more than one columns need
      to define either of these rules.</para>
    </note>

    <para>If a property uses more that one column, you must use the
    <literal>forColumn attribute to specify which column, the
    expressions are targeting.</para>

    <programlisting role="JAVA">@Entity
class User {
   @Type(type="com.acme.type.CreditCardType")
   @Columns( {
      @Column(name="credit_card_num"),
      @Column(name="exp_date") } )
   @ColumnTransformer(
      forColumn="credit_card_num", 
      read="decrypt(credit_card_num)", 
      write="encrypt(?)")
   public CreditCard getCreditCard() { return creditCard; }
   public void setCreditCard(CreditCard card) { this.creditCard = card; }
   private CreditCard creditCard;
}</programlisting>

    <para>Hibernate applies the custom expressions automatically whenever the
    property is referenced in a query. This functionality is similar to a
    derived-property <literal>formula with two differences:
    <itemizedlist spacing="compact">
        <listitem>
          <para>The property is backed by one or more columns that are
          exported as part of automatic schema generation.</para>
        </listitem>

        <listitem>
          <para>The property is read-write, not read-only.
        </listitem>
      </itemizedlist>

    <para>The write expression, if specified, must contain
    exactly one '?' placeholder for the value.</para>
  </section>

  <section id="mapping-database-object">
    <title>Auxiliary database objects

    <para>Auxiliary database objects allow for the CREATE and DROP of
    arbitrary database objects. In conjunction with Hibernate's schema
    evolution tools, they have the ability to fully define a user schema
    within the Hibernate mapping files. Although designed specifically for
    creating and dropping things like triggers or stored procedures, any SQL
    command that can be run via a
    <literal>java.sql.Statement.execute() method is valid (for
    example, ALTERs, INSERTS, etc.). There are essentially two modes for
    defining auxiliary database objects:</para>

    <para>The first mode is to explicitly list the CREATE and DROP commands in
    the mapping file:</para>

    <programlisting role="XML"><hibernate-mapping>
    ...
    <database-object>
        <create>CREATE TRIGGER my_trigger ...</create>
        <drop>DROP TRIGGER my_trigger</drop>
    </database-object>
</hibernate-mapping></programlisting>

    <para>The second mode is to supply a custom class that constructs the
    CREATE and DROP commands. This custom class must implement the
    <literal>org.hibernate.mapping.AuxiliaryDatabaseObject
    interface.</para>

    <programlisting role="XML"><hibernate-mapping>
    ...
    <database-object>
        <definition class="MyTriggerDefinition"/>
    </database-object>
</hibernate-mapping></programlisting>

    <para>Additionally, these database objects can be optionally scoped so
    that they only apply when certain dialects are used.</para>

    <programlisting role="XML"><hibernate-mapping>
    ...
    <database-object>
        <definition class="MyTriggerDefinition"/>
        <dialect-scope name="org.hibernate.dialect.Oracle9iDialect"/>
        <dialect-scope name="org.hibernate.dialect.Oracle10gDialect"/>
    </database-object>
</hibernate-mapping></programlisting>

    <note>
      <para>This feature is not supported in Annotations
    </note>
  </section>
</chapter>

Other Hibernate examples (source code examples)

Here is a short list of links related to this Hibernate basic_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.