Hibernate.org Community Documentation

- Prev
- Next

## Chapter 5. Basic O/R Mapping

## 5.1. Mapping declaration

Object/relational mappings can be defined in three approaches:

- using Java 5 annotations (via the Java Persistence 2 annotations)

- using JPA 2 XML deployment descriptors (described in chapter XXX)

- using the Hibernate legacy XML files approach known as hbm.xml

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.

JPA annotations are in the `javax.persistence.*` package. Hibernate specific extensions are in `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).

Here is an example of mapping

    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 { ... }

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.

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.

Here is an example mapping:

    <?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>

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 `not-null` attribute).

### 5.1.1. Entity

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

To mark an object as an entity in annotations, use the `@Entity` annotation.

    @Entity

    public class Flight implements Serializable {

        Long id;

        @Id

        public Long getId() { return id; }

        public void setId(Long id) { this.id = id; }

    }

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

`@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.

    @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; }
    }

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 `NamingStrategy` is applied.

## Tip

Be sure to use the database-level column names for the `columnNames` property of a `@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.

`@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.

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

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

- `selectBeforeUpdate` (defaults to false): specifies that Hibernate should never perform an SQL `UPDATE` unless it is certain that an object is actually modified. Only when a transient object has been associated with a new session using `update()`, will Hibernate perform an extra SQL `SELECT` to determine if an `UPDATE` is actually required. Use of `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 `Session`.

- `polymorphisms` (defaults to `IMPLICIT`): determines whether implicit or explicit query polymorphisms is used. 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. 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 `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.

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

- `optimisticLock` (defaults to `VERSION`): determines the optimistic locking strategy. If you enable `dynamicUpdate`, you will have a choice of optimistic locking strategies:

  - `version`: check the version/timestamp columns

  - `all`: check all columns

  - `dirty`: check the changed columns, allowing some concurrent updates

  - `none`: do not use optimistic locking

  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 `Session.merge()` is used).

## Tip

Be sure to import `@javax.persistence.Entity` to mark a class as an entity. It's a common mistake to import `@org.hibernate.annotations.Entity` by accident.

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 `@Immutable` annotation.

You can also alter how Hibernate deals with lazy initialization for this class. On `@Proxy`, use `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 `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.

`@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).

You can specific an arbitrary SQL WHERE condition to be used when retrieving objects of this class. Use `@Where` for that.

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

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 `@org.hibernate.annotations.Subselect`:

    @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; }
        ...
    }

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 `<subselect>` is available both as an attribute and a nested mapping element.

We will now explore the same options using the hbm.xml structure. You can declare a persistent class using the `class` element. For example:

    <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"                                  (16)
            entity-name="EntityName"                           (17)
            check="arbitrary sql check condition"              (18)
            rowxml:id="rowid"                                  (19)
            subselect="SQL expression"                         (20)
            abstract="true|false"                              (21)
            node="element-name"
    />

| `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.
| `table` (optional - defaults to the unqualified class name): the name of its database table.
| `discriminator-value` (optional - defaults to the class name): a value that distinguishes individual subclasses that is used for polymorphic behavior. Acceptable values include `null` and `not null`.
| `mutable` (optional - defaults to `true`): specifies that instances of the class are (not) mutable.
| `schema` (optional): overrides the schema name specified by the root `<hibernate-mapping>` element.
| `catalog` (optional): overrides the catalog name specified by the root `<hibernate-mapping>` element.
| `proxy` (optional): specifies an interface to use for lazy initializing proxies. You can specify the name of the class itself.
| `dynamic-update` (optional - defaults to `false`): specifies that `UPDATE` SQL should be generated at runtime and can contain only those columns whose values have changed.
| `dynamic-insert` (optional - defaults to `false`): specifies that `INSERT` SQL should be generated at runtime and contain only the columns whose values are not null.
| `select-before-update` (optional - defaults to `false`): specifies that Hibernate should never perform an SQL `UPDATE` unless it is certain that an object is actually modified. Only when a transient object has been associated with a new session using `update()`, will Hibernate perform an extra SQL `SELECT` to determine if an `UPDATE` is actually required.
| `polymorphisms` (optional - defaults to `implicit`): determines whether implicit or explicit query polymorphisms is used.
| `where` (optional): specifies an arbitrary SQL `WHERE` condition to be used when retrieving objects of this class.
| `persister` (optional): specifies a custom `ClassPersister`.
| `batch-size` (optional - defaults to `1`): specifies a "batch size" for fetching instances of this class by identifier.
| `optimistic-lock` (optional - defaults to `version`): determines the optimistic locking strategy.
(16) | `lazy` (optional): lazy fetching can be disabled by setting `lazy="false"`.
(17) | `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 Section 4.4, “Dynamic models” and Chapter 20, XML Mapping for more information.
(18) | `check` (optional): an SQL expression used to generate a multi-row check constraint for automatic schema generation.
(19) | `rowid` (optional): Hibernate can use ROWIDs on databases. On Oracle, for example, Hibernate can use the `rowid` extra column for fast updates once this option has been set to `rowid`. A ROWID is an implementation detail and represents the physical location of a stored tuple.
(20) | `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.
(21) | `abstract` (optional): is used to mark abstract superclasses in `<union-subclass>` hierarchies.

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

Here is how to do a virtual view (subselect) in 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>

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

### 5.1.2. Identifiers

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.

Mark the identifier property with `@Id`.

    @Entity
    public class Person {
       @Id Integer getId() { ... }
       ...
    }

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

    <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>

| `name` (optional): the name of the identifier property.
| `type` (optional): a name that indicates the Hibernate type.
| `column` (optional - defaults to the property name): the name of the primary key column.
| `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.
| `access` (optional - defaults to `property`): the strategy Hibernate should use for accessing the property value.

If the `name` attribute is missing, it is assumed that the class has no identifier property.

The `unsaved-value` attribute is almost never needed in Hibernate3 and indeed has no corresponding element in annotations.

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.

#### 5.1.2.1. Composite identifier

You can define a composite primary key through several syntaxes:

- use a component type to represent the identifier and map it as a property in the entity: you then annotated the property as `@EmbeddedId`. The component type has to be `Serializable`.

- map multiple properties as `@Id` properties: the identifier type is then the entity class itself and needs to be `Serializable`. This approach is unfortunately not standard and only supported by Hibernate.

- map multiple properties as `@Id` properties and declare an external class to be the identifier type. This class, which needs to be `Serializable`, is declared on the entity via the `@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 `@OneToOne` or a `@ManyToOne`).

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).

Let's explore all three cases using examples.

##### 5.1.2.1.1. id as a property using a component type

Here is a simple example of `@EmbeddedId`.

    @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;

    }

You can notice that the `UserId` class is serializable. To override the column mapping, use `@AttributeOverride`.

An embedded id can itself contains the primary key of an associated entity.

    @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

    }

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 `@MapsId` annotation. The `@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 `Customer.user` and the `CustomerId.userId` properties share the same underlying column (`user_fk` in this case).

## Tip

The component type used as identifier must implement `equals()` and `hashCode()`.

In practice, your code only sets the `Customer.user` property and the user id value is copied by Hibernate into the `CustomerId.userId` property.

## Warning

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

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

    @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

    }

Let's now rewrite these examples using the hbm.xml syntax.

    <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>

First a simple example:

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

Then an example showing how an association can be mapped.

    <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>

Notice a few things in the previous example:

- the order of the properties (and column) matters. It must be the same between the association and the primary key of the associated entity

- the many to one uses the same columns as the primary key and thus must be marked as read only (`insertable` and `updatable` to false).

- unlike with `@MapsId`, the id value of the associated entity is not transparently copied, check the `foreign` id generator for more information.

The last example shows how to map association directly in the embedded id component.

    <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>

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

##### 5.1.2.1.2. Multiple id properties without identifier type

Another, arguably more natural, approach is to place `@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.

    @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

    }

In this case `Customer` is its own identifier representation: it must implement `Serializable` and must implement `equals()` and `hashCode()`.

In hbm.xml, the same mapping is:

    <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>

##### 5.1.2.1.3. Multiple id properties with with a dedicated identifier type

`@IdClass` on an entity points to the class (component) representing the identifier of the class. The properties marked `@Id` on the entity must have their corresponding property on the `@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.

## Warning

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.

    @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

    }

`Customer` and `CustomerId` do have the same properties `customerNumber` as well as `user`. `CustomerId` must be `Serializable` and implement `equals()` and `hashCode()`.

While not JPA standard, Hibernate let's you declare the vanilla associated property in the `@IdClass`.

    @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;

    }

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

Here are the equivalent on hbm.xml files:

    <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>

#### 5.1.2.2. Identifier generator

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

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

- IDENTITY: supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type `long`, `short` or `int`.

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

- TABLE (called `MultipleHiLoPerTableGenerator` in Hibernate) : uses a hi/lo algorithm to efficiently generate identifiers of type `long`, `short` or `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.

- AUTO: selects `IDENTITY`, `SEQUENCE` or `TABLE` depending upon the capabilities of the underlying database.

## Important

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 `hibernate.id.new_generator_mappings=true`. These new generators are more efficient and closer to the JPA 2 specification semantic.

However they are not backward compatible with existing Hibernate based application (if a sequence or a table is used for id generation). See XXXXXXX ??? for more information on how to activate them.

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

    @Entity
    public class Customer {
       @Id @GeneratedValue
       Integer getId() { ... };
    }

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

`SEQUENCE` and `TABLE` require additional configurations that you can set using `@SequenceGenerator` and `@TableGenerator`:

- `name`: name of the generator

- `table` / `sequenceName`: name of the table or the sequence (defaulting respectively to `hibernate_sequences` and `hibernate_sequence`)

- `catalog` / `schema`:

- `initialValue`: the value from which the id is to start generating

- `allocationSize`: the amount to increment by when allocating id numbers from the generator

In addition, the `TABLE` strategy also let you customize:

- `pkColumnName`: the column name containing the entity identifier

- `valueColumnName`: the column name containing the identifier value

- `pkColumnValue`: the entity identifier

- `uniqueConstraints`: any potential column constraint on the table containing the ids

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

    @Id

    @GeneratedValue(

        strategy=GenerationType.SEQUENCE,

        generator="SEQ_GEN")

    @javax.persistence.SequenceGenerator(

        name="SEQ_GEN",

        sequenceName="my_sequence",

        allocationSize=20

    )

    public Integer getId() { ... }

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 ???):

    <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

    )

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

## Note

Package level definition is not supported by the JPA specification. However, you can use the `@GenericGenerator` at the package level (see ???).

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 `org.hibernate.id.IdentifierGenerator`.

To define a custom generator, use the `@GenericGenerator` annotation (and its plural counter part `@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 `@GenericGenerator` and assigning it via `@GeneratedValue.generator`, the `@GeneratedValue.strategy` is ignored: leave it blank.

    @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() {

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

    <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>

##### 5.1.2.2.1. Various additional generators

All generators implement the interface `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:

`increment`

  generates identifiers of type `long`, `short` or `int` that are unique only when no other process is inserting data into the same table. Do not use in a cluster.

`identity`

  supports identity columns in DB2, MySQL, MS SQL Server, Sybase and HypersonicSQL. The returned identifier is of type `long`, `short` or `int`.

`sequence`

  uses a sequence in DB2, PostgreSQL, Oracle, SAP DB, McKoi or a generator in Interbase. The returned identifier is of type `long`, `short` or `int`

`hilo`

  uses a hi/lo algorithm to efficiently generate identifiers of type `long`, `short` or `int`, given a table and column (by default `hibernate_unique_key` and `next_hi` respectively) as a source of hi values. The hi/lo algorithm generates identifiers that are unique only for a particular database.

`seqhilo`

  uses a hi/lo algorithm to efficiently generate identifiers of type `long`, `short` or `int`, given a named database sequence.

`uuid`

  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.

`uuid2`

  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 `java.util.UUID`, `java.lang.String` or as a byte array of length 16 (`byte[16]`). The "generation strategy" is defined by the interface `org.hibernate.id.UUIDGenerationStrategy`. The generator defines 2 configuration parameters for defining which generation strategy to use:

  `uuid_gen_strategy_class`

    Names the UUIDGenerationStrategy class to use

  `uuid_gen_strategy`

    Names the UUIDGenerationStrategy instance to use

  Out of the box, comes with the following strategies:

  - `org.hibernate.id.uuid.StandardRandomStrategy` (the default) - generates "version 3" (aka, "random") UUID values via the `randomUUID` method of `java.util.UUID`

  - `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 `org.hibernate.id.UUIDGenerationStrategy` contract. Two such libraries known at time of this writing include http://johannburkard.de/software/uuid/ and http://commons.apache.org/sandbox/id/uuid.html

`guid`

  uses a database-generated GUID string on MS SQL Server and MySQL.

`native`

  selects `identity`, `sequence` or `hilo` depending upon the capabilities of the underlying database.

`assigned`

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

`select`

  retrieves a primary key, assigned by a database trigger, by selecting the row by some unique key and retrieving the primary key value.

`foreign`

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

`sequence-identity`

  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.

##### 5.1.2.2.2. Hi/lo algorithm

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.

    <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>

    <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>

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

##### 5.1.2.2.3. UUID algorithm

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.

##### 5.1.2.2.4. Identity columns and sequences

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

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

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

For cross-platform development, the `native` strategy will, depending on the capabilities of the underlying database, choose from the `identity`, `sequence` and `hilo` strategies.

##### 5.1.2.2.5. Assigned identifiers

If you want the application to assign identifiers, as opposed to having Hibernate generate them, you can use the `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 `@GeneratedValue` nor `<generator>` elements.

The `assigned` generator makes Hibernate use `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 `Interceptor.isUnsaved()`.

##### 5.1.2.2.6. Primary keys assigned by triggers

Hibernate does not generate DDL with triggers. It is for legacy schemas only.

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

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

##### 5.1.2.2.7. Identity copy (foreign generator)

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.

    @Entity

    class MedicalHistory implements Serializable {

      @Id @OneToOne

      @JoinColumn(name = "person_id")

      Person patient;

    }

    @Entity

    public class Person implements Serializable {

      @Id @GeneratedValue Integer id;

    }

Or alternatively

    @Entity

    class MedicalHistory implements Serializable {

      @Id Integer id;

      @MapsId @OneToOne

      @JoinColumn(name = "patient_id")

      Person patient;

    }

    @Entity

    class Person {

      @Id @GeneratedValue Integer id;

    }

In hbm.xml use the following approach:

    <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>

#### 5.1.2.3. Enhanced identifier generators

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.

The first of these new generators is `org.hibernate.id.enhanced.SequenceStyleGenerator` which is intended, firstly, as a replacement for the `sequence` generator and, secondly, as a better portability generator than `native`. This is because `native` generally chooses between `identity` and `sequence` which have largely different semantics that can cause subtle issues in applications eyeing portability. `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 `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:

- `sequence_name` (optional, defaults to `hibernate_sequence`): the name of the sequence or table to be used.

- `initial_value` (optional, defaults to `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".

- `increment_size` (optional - defaults to `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".

- `force_table_use` (optional - defaults to `false`): should we force the use of a table as the backing structure even though the dialect might support sequence?

- `value_column` (optional - defaults to `next_val`): only relevant for table structures, it is the name of the column on the table which is used to hold the value.

- `optimizer` (optional - defaults to `none`): See Section 5.1.2.3.1, “Identifier generator optimization”

The second of these new generators is `org.hibernate.id.enhanced.TableGenerator`, which is intended, firstly, as a replacement for the `table` generator, even though it actually functions much more like `org.hibernate.id.MultipleHiLoPerTableGenerator`, and secondly, as a re-implementation of `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:

- `table_name` (optional - defaults to `hibernate_sequences`): the name of the table to be used.

- `value_column_name` (optional - defaults to `next_val`): the name of the column on the table that is used to hold the value.

- `segment_column_name` (optional - defaults to `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.

- `segment_value` (optional - defaults to `default`): The "segment key" value for the segment from which we want to pull increment values for this generator.

- `segment_value_length` (optional - defaults to `255`): Used for schema generation; the column size to create this segment key column.

- `initial_value` (optional - defaults to `1`): The initial value to be retrieved from the table.

- `increment_size` (optional - defaults to `1`): The value by which subsequent calls to the table should differ.

- `optimizer` (optional - defaults to `??`): See Section 5.1.2.3.1, “Identifier generator optimization”.

##### 5.1.2.3.1. Identifier generator optimization

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 (Section 5.1.2.3, “Enhanced identifier generators” support this operation.

- `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.

- `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 `increment_size` is multiplied by that value in memory to define a group "hi value".

- `pooled`: as with the case of `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, `increment_size` refers to the values coming from the database.

#### 5.1.2.4. Partial identifier generation

Hibernate supports the automatic generation of some of the identifier properties. Simply use the `@GeneratedValue` annotation on one or several id properties.

## Warning

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

    @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;

    }

You can also generate properties inside an `@EmbeddedId` class.

### 5.1.3. Optimistic locking properties (optional)

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.

You can use two approaches: a dedicated version number or a timestamp.

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 `unsaved-value` strategies are specified. 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.

#### 5.1.3.1. Version number

You can add optimistic locking capability to an entity using the `@Version` annotation:

    @Entity

    public class Flight implements Serializable {

    ...

        @Version

        @Column(name="OPTLOCK")

        public Integer getVersion() { ... }

    }

The version property will be mapped to the `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).

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

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 `LockModeType.OPTIMISTIC_FORCE_INCREMENT` or `LockModeType.PESSIMISTIC_FORCE_INCREMENT`.

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

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

    <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|."
    />

| `column` (optional - defaults to the property name): the name of the column holding the version number.
| `name`: the name of a property of the persistent class.
| `type` (optional - defaults to `integer`): the type of the version number.
| `access` (optional - defaults to `property`): the strategy Hibernate uses to access the property value.
| `unsaved-value` (optional - defaults to `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. `Undefined` specifies that the identifier property value should be used.
| `generated` (optional - defaults to `never`): specifies that this version property value is generated by the database. See the discussion of generated properties for more information.
| `insert` (optional - defaults to `true`): specifies whether the version column should be included in SQL insert statements. It can be set to `false` if the database column is defined with a default value of `0`.

#### 5.1.3.2. Timestamp

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.

Simply mark a property of type `Date` or `Calendar` as `@Version`.

    @Entity

    public class Flight implements Serializable {

    ...

        @Version

        public Date getLastUpdate() { ... }

    }

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

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

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

    <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|."
    />

| `column` (optional - defaults to the property name): the name of a column holding the timestamp.
| `name`: the name of a JavaBeans style property of Java type `Date` or `Timestamp` of the persistent class.
| `access` (optional - defaults to `property`): the strategy Hibernate uses for accessing the property value.
| `unsaved-value` (optional - defaults to `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. `Undefined` specifies that the identifier property value should be used.
| `source` (optional - defaults to `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 `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).
| `generated` (optional - defaults to `never`): specifies that this timestamp property value is actually generated by the database. See the discussion of generated properties for more information.

## Note

`<Timestamp>` is equivalent to `<version type="timestamp">`. And `<timestamp source="db">` is equivalent to `<version type="dbtimestamp">`

### 5.1.4. Property

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.

#### 5.1.4.1. Property mapping with annotations

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 `@Transient`. Not having an annotation for your property is equivalent to the appropriate `@Basic` annotation.

The `@Basic` annotation allows you to declare the fetching strategy for a property. If set to `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 `EAGER`. You can also mark a property as not optional thanks to the `@Basic.optional` attribute. This will ensure that the underlying column are not nullable (if possible). Note that a better approach is to use the `@NotNull` annotation of the Bean Validation specification.

Let's look at a few examples:

    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

`counter`, a transient field, and `lengthInMeter`, a method annotated as `@Transient`, and will be ignored by the Hibernate. `name`, `length`, and `firstname` properties are mapped persistent and eagerly fetched (the default for simple properties). The `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.

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 `@Enumerated` annotation as shown in the `note` property example.

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 `DATE`, `TIME`, or `TIMESTAMP` precision (ie the actual date, only the time, or both). Use the `@Temporal` annotation to fine tune that.

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

    @Lob

    public String getFullText() {

        return fullText;

    }

    @Lob

    public byte[] getFullCode() {

        return fullCode;

    }

If the property type implements `java.io.Serializable` and is not a basic type, and if the property is not annotated with `@Lob`, then the Hibernate `serializable` type is used.

##### 5.1.4.1.1. Type

You can also manually specify a type using the `@org.hibernate.annotations.Type` and some parameters if needed. `@Type.type` could be:

1. The name of a Hibernate basic type: `integer, string, character, date, timestamp, float, binary, serializable, object, blob` etc.

2. The name of a Java class with a default basic type: `int, float, char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob` etc.

3. The name of a serializable Java class.

4. The class name of a custom type: `com.illflow.type.MyCustomType` etc.

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.

`@org.hibernate.annotations.TypeDef` and `@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 `PhoneNumer`, it delegates the persistence strategy to the custom mapping type `PhoneNumberType`. However, properties belonging to other classes, too, can delegate their persistence strategy to `PhoneNumberType`, by explicitly using the `@Type` annotation.

## Note

Package level annotations are placed in a file named `package-info.java` in the appropriate package. Place your annotations before the package declaration.

    @TypeDef(

       name = "phoneNumber",

       defaultForType = PhoneNumber.class,

       typeClass = PhoneNumberType.class

    )

    @Entity

    public class ContactDetails {

       [...]

       private PhoneNumber localPhoneNumber;

       @Type(type="phoneNumber")

       private OverseasPhoneNumber overseasPhoneNumber;

       [...]

    }

The following example shows the usage of the `parameters` attribute to customize the TypeDef.

    //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() {

        ...

    }

When using composite user type, you will have to express column definitions. The `@Columns` has been introduced for that purpose.

    @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;

        ...

    }

##### 5.1.4.1.2. Access type

By default the access type of a class hierarchy is defined by the position of the `@Id` or `@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

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.

However in some situations, you need to:

- force the access type of the entity hierarchy

- override the access type of a specific entity in the class hierarchy

- override the access type of an embeddable type

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.

To force the access type on a given class, use the `@Access` annotation as showed below:

    @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

    }

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

    @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 = ...; }

    }

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

## @org.hibernate.annotations.AccessType

The annotation `@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.

##### 5.1.4.1.3. Optimistic lock

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 `@OptimisticLock(excluded=true)`.

More formally, specifies that updates to this property do not require acquisition of the optimistic lock.

##### 5.1.4.1.4. Declaring column attributes

The column(s) used for a property mapping can be defined using the `@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:

- not annotated at all

- annotated with `@Basic`

- annotated with `@Version`

- annotated with `@Lob`

- annotated with `@Temporal`

    @Entity

    public class Flight implements Serializable {

    ...

    @Column(updatable = false, name = "flight_name", nullable = false, length=50)

    public String getName() { ... }

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

This annotation can be applied to regular properties as well as `@Id` or `@Version` properties.

    @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

| `name` (optional): the column name (default to the property name)
| `unique` (optional): set a unique constraint on this column or not (default false)
| `nullable` (optional): set the column as nullable (default true).
| `insertable` (optional): whether or not the column will be part of the insert statement (default true)
| `updatable` (optional): whether or not the column will be part of the update statement (default true)
| `columnDefinition` (optional): override the sql DDL fragment for this particular column (non portable)
| `table` (optional): define the targeted table (default primary table)
| `length` (optional): column length (default 255)
| `precision` (optional): column decimal precision (default 0)
| `scale` (optional): column decimal scale if useful (default 0)

##### 5.1.4.1.5. Formula

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).

    @Formula("obj_length * obj_height * obj_width")

    public long getObjectVolume()

The SQL fragment can be as complex as you want and even include subselects.

##### 5.1.4.1.6. Non-annotated property defaults

If a property is not annotated, the following rules apply:

- If the property is of a single type, it is mapped as @Basic

- Otherwise, if the type of the property is annotated as @Embeddable, it is mapped as @Embedded

- Otherwise, if the type of the property is `Serializable`, it is mapped as `@Basic` in a column holding the object in its serialized version

- Otherwise, if the type of the property is `java.sql.Clob` or `java.sql.Blob`, it is mapped as `@Lob` with the appropriate `LobType`

#### 5.1.4.2. Property mapping with hbm.xml

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

    <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"
    />

| `name`: the name of the property, with an initial lowercase letter.
| `column` (optional - defaults to the property name): the name of the mapped database table column. This can also be specified by nested `<column>` element(s).
| `type` (optional): a name that indicates the Hibernate type.
| `update, insert` (optional - defaults to `true`): specifies that the mapped columns should be included in SQL `UPDATE` and/or `INSERT` statements. Setting both to `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.
| `formula` (optional): an SQL expression that defines the value for a computed property. Computed properties do not have a column mapping of their own.
| `access` (optional - defaults to `property`): the strategy Hibernate uses for accessing the property value.
| `lazy` (optional - defaults to `false`): specifies that this property should be fetched lazily when the instance variable is first accessed. It requires build-time bytecode instrumentation.
| `unique` (optional): enables the DDL generation of a unique constraint for the columns. Also, allow this to be the target of a `property-ref`.
| `not-null` (optional): enables the DDL generation of a nullability constraint for the columns.
| `optimistic-lock` (optional - defaults to `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.
| `generated` (optional - defaults to `never`): specifies that this property value is actually generated by the database. See the discussion of generated properties for more information.

typename could be:

1. The name of a Hibernate basic type: `integer, string, character, date, timestamp, float, binary, serializable, object, blob` etc.

2. The name of a Java class with a default basic type: `int, float, char, java.lang.String, java.util.Date, java.lang.Integer, java.sql.Clob` etc.

3. The name of a serializable Java class.

4. The class name of a custom type: `com.illflow.type.MyCustomType` etc.

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 `type` attribute. For example, to distinguish between `Hibernate.DATE` and `Hibernate.TIMESTAMP`, or to specify a custom type.

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 `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 `org.hibernate.property.PropertyAccessor`.

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 `SELECT` clause subquery in the SQL query that loads an instance:

    <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 )"/>

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

### 5.1.5. Embedded objects (aka components)

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

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 `@Embeddable` annotation. It is possible to override the column mapping of an embedded object for a particular entity using the `@Embedded` and `@AttributeOverride` annotation in the associated property:

    @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;

        ...

    }

    @Embeddable

    public class Address implements Serializable {

        String city;

        Country nationality; //no overriding here

    }

    @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; }

        ...

    }

An embeddable object inherits the access type of its owning entity (note that you can override that using the `@Access` annotation).

The `Person` entity has two component properties, `homeAddress` and `bornIn`. `homeAddress` property has not been annotated, but Hibernate will guess that it is a persistent component by looking for the `@Embeddable` annotation in the Address class. We also override the mapping of a column name (to `bornCountryName`) with the `@Embedded` and `@AttributeOverride` annotations for each mapped attribute of `Country`. As you can see, `Country` 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.

        @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;

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

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

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 `NamingStrategy` interface. You can write a strategy that prevent name clashing in such a situation. `DefaultComponentSafeNamingStrategy` is an example of this.

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

In XML, use the `<component>` element.

    <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>

| `name`: the name of the property.
| `class` (optional - defaults to the property type determined by reflection): the name of the component (child) class.
| `insert`: do the mapped columns appear in SQL `INSERTs`?
| `update`: do the mapped columns appear in SQL `UPDATEs`?
| `access` (optional - defaults to `property`): the strategy Hibernate uses for accessing the property value.
| `lazy` (optional - defaults to `false`): specifies that this component should be fetched lazily when the instance variable is first accessed. It requires build-time bytecode instrumentation.
| `optimistic-lock` (optional - defaults to `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.
| `unique` (optional - defaults to `false`): specifies that a unique constraint exists upon all mapped columns of the component.

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

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

The `<dynamic-component>` element allows a `Map` to be mapped as a component, where the property names refer to keys of the map. See Section 9.5, “Dynamic components” for more information. This feature is not supported in annotations.

### 5.1.6. Inheritance strategy

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

- Single table per class hierarchy strategy: a single table hosts all the instances of a class hierarchy

- 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

- 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.

#### 5.1.6.1. Single table per class hierarchy strategy

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

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.

    @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 { ... }

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

    <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>

| `name`: the fully qualified class name of the subclass.
| `discriminator-value` (optional - defaults to the class name): a value that distinguishes individual subclasses.
| `proxy` (optional): specifies a class or interface used for lazy initializing proxies.
| `lazy` (optional - defaults to `true`): setting `lazy="false"` disables the use of lazy fetching.

For information about inheritance mappings see Chapter 10, Inheritance mapping.

##### 5.1.6.1.1. Discriminator

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: `string`, `character`, `integer`, `byte`, `short`, `boolean`, `yes_no`, `true_false`.

Use the `@DiscriminatorColumn` to define the discriminator column as well as the discriminator type.

## Note

`The enum DiscriminatorType` used in `javax.persitence.DiscriminatorColumn` only contains the values `STRING`, `CHAR` and `INTEGER` which means that not all Hibernate supported types are available via the `@DiscriminatorColumn` annotation.

You can also use `@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 `@DiscriminatorColumn` and `@DiscriminatorFormula` are to be set on the root entity (once per persisted hierarchy).

`@org.hibernate.annotations.DiscriminatorOptions` allows to optionally specify Hibernate specific discriminator options which are not standardized in JPA. The available options are `force` and `insert`. The `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 `force` is set to `true` Hibernate will specify the allowed discriminator values in the `SELECT` query, even when retrieving all instances of the root class. The second option - `insert` - tells Hibernate whether or not to include the discriminator column in SQL `INSERTs`. Usually the column should be part of the `INSERT` statement, but if your discriminator column is also part of a mapped composite identifier you have to set this option to `false`.

## Tip

There is also a `@org.hibernate.annotations.ForceDiscriminator` annotation which is deprecated since version 3.6. Use `@DiscriminatorOptions` instead.

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 `@DiscriminatorValue` on a class, the fully qualified class name is used.

    @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 { ... }

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

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

| `column` (optional - defaults to `class`): the name of the discriminator column.
| `type` (optional - defaults to `string`): a name that indicates the Hibernate type
| `force` (optional - defaults to `false`): "forces" Hibernate to specify the allowed discriminator values, even when retrieving all instances of the root class.
| `insert` (optional - defaults to `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 `INSERTs`.
| `formula` (optional): an arbitrary SQL expression that is executed when a type has to be evaluated. It allows content-based discrimination.

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

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

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

#### 5.1.6.2. Joined subclass strategy

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 `@PrimaryKeyJoinColumn`s or the `<key>` element.

    @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; }

    }

## Note

The table name still defaults to the non qualified class name. Also if `@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.

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

    <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>

| `name`: the fully qualified class name of the subclass.
| `table`: the name of the subclass table.
| `proxy` (optional): specifies a class or interface to use for lazy initializing proxies.
| `lazy` (optional, defaults to `true`): setting `lazy="false"` disables the use of lazy fetching.

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:

    <?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>

For information about inheritance mappings see Chapter 10, Inheritance mapping.

#### 5.1.6.3. Table per class strategy

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.

    @Entity

    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

    public class Flight implements Serializable { ... }

Or in hbm.xml:

    <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>

| `name`: the fully qualified class name of the subclass.
| `table`: the name of the subclass table.
| `proxy` (optional): specifies a class or interface to use for lazy initializing proxies.
| `lazy` (optional, defaults to `true`): setting `lazy="false"` disables the use of lazy fetching.

No discriminator column or key column is required for this mapping strategy.

For information about inheritance mappings see Chapter 10, Inheritance mapping.

#### 5.1.6.4. Inherit properties from superclasses

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 `@MappedSuperclass`.

    @MappedSuperclass

    public class BaseEntity {

        @Basic

        @Temporal(TemporalType.TIMESTAMP)

        public Date getLastUpdate() { ... }

        public String getLastUpdater() { ... }

        ...

    }

    @Entity class Order extends BaseEntity {

        @Id public Integer getId() { ... }

        ...

    }

In database, this hierarchy will be represented as an `Order` table having the `id`, `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.

## Note

Properties from superclasses not mapped as `@MappedSuperclass` are ignored.

## Note

The default access type (field or methods) is used, unless you use the `@Access` annotation.

## Note

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

## Note

It is allowed to mark a class as `@MappedSuperclass` in the middle of the mapped inheritance hierarchy.

## Note

Any class in the hierarchy non annotated with `@MappedSuperclass` nor `@Entity` will be ignored.

You can override columns defined in entity superclasses at the root entity level using the `@AttributeOverride` annotation.

    @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 {

        ...

    }

The `altitude` property will be persisted in an `fld_altitude` column of table `Plane` and the propulsion association will be materialized in a `fld_propulsion_fk` foreign key column.

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

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

#### 5.1.6.5. Mapping one entity to several tables

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

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

    @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;

        }

    }

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

There is also additional tuning accessible via the `@org.hibernate.annotations.Table` annotation:

- `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 `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.

- `inverse`: If true, Hibernate will not try to insert or update the properties defined by this join. Default to false.

- `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.

- `foreignKey`: defines the Foreign Key name of a secondary table pointing back to the primary table.

Make sure to use the secondary table name in the `appliesto` property

    @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;

        }

    }

In hbm.xml, use the `<join>` element.

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

            <key ... />

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

| `table`: the name of the joined table.
| `schema` (optional): overrides the schema name specified by the root `<hibernate-mapping>` element.
| `catalog` (optional): overrides the catalog name specified by the root `<hibernate-mapping>` element.
| `fetch` (optional - defaults to `join`): if set to `join`, the default, Hibernate will use an inner join to retrieve a `<join>` defined by a class or its superclasses. It will use an outer join for a `<join>` defined by a subclass. If set to `select` then Hibernate will use a sequential select for a `<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 `<join>` defined by the class and its superclasses.
| `inverse` (optional - defaults to `false`): if enabled, Hibernate will not insert or update the properties defined by this join.
| `optional` (optional - defaults to `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.

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

    <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>
        ...

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.

### 5.1.7. Mapping one to one and one to many associations

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.

To mark an association, use either `@ManyToOne` or `@OnetoOne`.

`@ManyToOne` and `@OneToOne` have a parameter named `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.

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.

1. basic operations, which include: `persist, merge, delete, save-update, evict, replicate, lock and refresh`;

2. special values: `delete-orphan` or `all` ;

3. comma-separated combinations of operation names: `cascade="persist,merge,evict"` or `cascade="all,delete-orphan"`. See Section 11.11, “Transitive persistence” for a full explanation. Note that single valued many-to-one associations do not support orphan delete.

By default, single point associations are eagerly fetched in JPA 2. You can mark it as lazily fetched by using `@ManyToOne(fetch=FetchType.LAZY)` 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 `@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.

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

#### 5.1.7.1. Using a foreign key or an association table

An ordinary association to another persistent class is declared using a

- `@ManyToOne` if several entities can point to the the target entity

- `@OneToOne` if only a single entity can point to the the target entity

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

    @Entity

    public class Flight implements Serializable {

        @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )

        @JoinColumn(name="COMP_ID")

        public Company getCompany() {

            return company;

        }

        ...

    }

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

    @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 {

        ...

    }

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

    @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;

        }

        ...

    }

## Note

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

    @Entity

    public class Ticket implements Serializable {

        @ManyToOne

        @JoinColumnOrFormula(formula="(firstname + ' ' + lastname)")

        public Person getOwner() {

            return person;

        }

        ...

    }

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

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 `@NotFound` annotation.

Example 5.1. @NotFound annotation

    @Entity

    public class Child {

        ...

        @ManyToOne

        @NotFound(action=NotFoundAction.IGNORE)

        public Parent getParent() { ... }

        ...

    }

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.

Example 5.2. @OnDelete annotation

    @Entity

    public class Child {

        ...

        @ManyToOne

        @OnDelete(action=OnDeleteAction.CASCADE)

        public Parent getParent() { ... }

        ...

    }

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

Example 5.3. @ForeignKey annotation

    @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

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 `@JoinColumn.referenceColumnName`.

    @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
    }

This is not encouraged however and should be reserved to legacy mappings.

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

    <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"
    />

| `name`: the name of the property.
| `column` (optional): the name of the foreign key column. This can also be specified by nested `<column>` element(s).
| `class` (optional - defaults to the property type determined by reflection): the name of the associated class.
| `cascade` (optional): specifies which operations should be cascaded from the parent object to the associated object.
| `fetch` (optional - defaults to `select`): chooses between outer-join fetching or sequential select fetching.
| `update, insert` (optional - defaults to `true`): specifies that the mapped columns should be included in SQL `UPDATE` and/or `INSERT` statements. Setting both to `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.
| `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.
| `access` (optional - defaults to `property`): the strategy Hibernate uses for accessing the property value.
| `unique` (optional): enables the DDL generation of a unique constraint for the foreign-key column. By allowing this to be the target of a `property-ref`, you can make the association multiplicity one-to-one.
| `not-null` (optional): enables the DDL generation of a nullability constraint for the foreign key columns.
| `optimistic-lock` (optional - defaults to `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.
| `lazy` (optional - defaults to `proxy`): by default, single point associations are proxied. `lazy="no-proxy"` specifies that the property should be 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.
| `not-found` (optional - defaults to `exception`): specifies how foreign keys that reference missing rows will be handled. `ignore` will treat a missing row as a null association.
| `entity-name` (optional): the entity name of the associated class.
| `formula` (optional): an SQL expression that defines the value for a computed foreign key.

Setting a value of the `cascade` attribute to any meaningful value other than `none` will propagate certain operations to the associated object. The meaningful values are divided into three categories. First, basic operations, which include: `persist, merge, delete, save-update, evict, replicate, lock and refresh`; second, special values: `delete-orphan`; and third,`all` comma-separated combinations of operation names: `cascade="persist,merge,evict"` or `cascade="all,delete-orphan"`. See Section 11.11, “Transitive persistence” for a full explanation. Note that single valued, many-to-one and one-to-one, associations do not support orphan delete.

Here is an example of a typical `many-to-one` declaration:

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

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 `Product` class had a unique serial number that is not the primary key. The `unique` attribute controls Hibernate's DDL generation with the SchemaExport tool.

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

Then the mapping for `OrderItem` might use:

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

This is not encouraged, however.

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

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

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

#### 5.1.7.2. Sharing the primary key with the associated entity

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.

Example 5.4. One to One association

    @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() { ...}

    }

## Note

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 `@OneToOne(optional=false)`.

In hbm.xml, use the following mapping.

    <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"
    />

| `name`: the name of the property.
| `class` (optional - defaults to the property type determined by reflection): the name of the associated class.
| `cascade` (optional): specifies which operations should be cascaded from the parent object to the associated object.
| `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 `save()` and `delete()` are cascaded, and determines whether the association can be proxied. It is also used by the schema export tool.
| `fetch` (optional - defaults to `select`): chooses between outer-join fetching or sequential select fetching.
| `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.
| `access` (optional - defaults to `property`): the strategy Hibernate uses for accessing the property value.
| `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 `org.hibernate.test.onetooneformula` for an example.
| `lazy` (optional - defaults to `proxy`): by default, single point associations are proxied. `lazy="no-proxy"` specifies that the property should be fetched lazily when the instance variable is first accessed. It requires build-time bytecode instrumentation. `lazy="false"` specifies that the association will always be eagerly fetched. Note that if `constrained="false"`, proxying is impossible and Hibernate will eagerly fetch the association.
| `entity-name` (optional): the entity name of the associated class.

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.

For a primary key association, add the following mappings to `Employee` and `Person` respectively:

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

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

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 `foreign`:

    <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>

A newly saved instance of `Person` is assigned the same primary key value as the `Employee` instance referred with the `employee` property of that `Person`.

### 5.1.8. Natural-id

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 `@NaturalId` or map them inside the `<natural-id>` element. Hibernate will generate the necessary unique key and nullability constraints and, as a result, your mapping will be more self-documenting.

    @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();

Or in XML,

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

It is recommended that you implement `equals()` and `hashCode()` to compare the natural key properties of the entity.

This mapping is not intended for use with entities that have natural primary keys.

- `mutable` (optional - defaults to `false`): by default, natural identifier properties are assumed to be immutable (constant).

### 5.1.9. Any

There is one more type of property mapping. The `@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.

The `@Any` annotation describes the column holding the metadata information. To link the value of the metadata information and an actual entity type, The `@AnyDef` and `@AnyDefs` annotations are used. The `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 `idType`. You must specify the mapping from values of the `metaType` to class names.

    @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;

    }

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

    //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;

        }

The hbm.xml equivalent is:

    <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>

## Note

You cannot mutualize the metadata in hbm.xml as you can in annotations.

    <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>

| `name`: the property name.
| `id-type`: the identifier type.
| `meta-type` (optional - defaults to `string`): any type that is allowed for a discriminator mapping.
| `cascade` (optional- defaults to `none`): the cascade style.
| `access` (optional - defaults to `property`): the strategy Hibernate uses for accessing the property value.
| `optimistic-lock` (optional - defaults to `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.

### 5.1.10. Properties

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 `property-ref`. It is also a convenient way to define a multi-column unique constraint. For example:

    <properties
            name="logicalName"
            insert="true|false"
            update="true|false"
            optimistic-lock="true|false"
            unique="true|false"
    >

            <property ...../>
            <many-to-one .... />
            ........
    </properties>

| `name`: the logical name of the grouping. It is not an actual property name.
| `insert`: do the mapped columns appear in SQL `INSERTs`?
| `update`: do the mapped columns appear in SQL `UPDATEs`?
| `optimistic-lock` (optional - defaults to `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.
| `unique` (optional - defaults to `false`): specifies that a unique constraint exists upon all mapped columns of the component.

For example, if we have the following `<properties>` mapping:

    <class name="Person">
        <id name="personNumber"/>

        ...
        <properties name="name"
                unique="true" update="false">
            <property name="firstName"/>
            <property name="initial"/>
            <property name="lastName"/>
        </properties>
    </class>

You might have some legacy data association that refers to this unique key of the `Person` table, instead of to the primary key:

    <many-to-one name="owner"
             class="Person" property-ref="name">
        <column name="firstName"/>
        <column name="initial"/>
        <column name="lastName"/>
    </many-to-one>

## Note

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

    @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
    }

The use of this outside the context of mapping legacy data is not recommended.

### 5.1.11. Some hbm.xml specificities

The hbm.xml structure has some specificities naturally not present when using annotations, let's describe them briefly.

#### 5.1.11.1. Doctype

All XML mappings should declare the doctype shown. The actual DTD can be found at the URL above, in the directory `hibernate-x.x.x/src/org/hibernate` , or in `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.

##### 5.1.11.1.1. EntityResolver

Hibernate will first attempt to resolve DTDs in its classpath. It does this is by registering a custom `org.xml.sax.EntityResolver` implementation with the SAXReader it uses to read in the xml files. This custom `EntityResolver` recognizes two different systemId namespaces:

- a `hibernate namespace` is recognized whenever the resolver encounters a systemId starting with `http://www.hibernate.org/dtd/`. The resolver attempts to resolve these entities via the classloader which loaded the Hibernate classes.

- a `user namespace` is recognized whenever the resolver encounters a systemId using a `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.

The following is an example of utilizing user namespacing:

    <?xml version="1.0"?>

    <!DOCTYPE hibernate-mapping PUBLIC

            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" [

        <!ENTITY types SYSTEM "classpath://your/domain/types.xml">

    ]>

    <hibernate-mapping package="your.domain">

        <class name="MyEntity">

            <id name="id" type="my-custom-id-type">

                ...

            </id>

        <class>

        &types;

    </hibernate-mapping>

Where `types.xml` is a resource in the `your.domain` package and contains a custom typedef.

#### 5.1.11.2. Hibernate-mapping

This element has several optional attributes. The `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 `default-cascade` attribute specifies what cascade style should be assumed for properties and collections that do not specify a `cascade` attribute. By default, the `auto-import` attribute allows you to use unqualified class names in the query language.

    <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"
     />

| `schema` (optional): the name of a database schema.
| `catalog` (optional): the name of a database catalog.
| `default-cascade` (optional - defaults to `none`): a default cascade style.
| `default-access` (optional - defaults to `property`): the strategy Hibernate should use for accessing all properties. It can be a custom implementation of `PropertyAccessor`.
| `default-lazy` (optional - defaults to `true`): the default value for unspecified `lazy` attributes of class and collection mappings.
| `auto-import` (optional - defaults to `true`): specifies whether we can use unqualified class names of classes in this mapping in the query language.
| `package` (optional): specifies a package prefix to use for unqualified class names in the mapping document.

If you have two persistent classes with the same unqualified name, you should set `auto-import="false"`. An exception will result if you attempt to assign two classes to the same "imported" name.

The `hibernate-mapping` element allows you to nest several persistent `<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, `Cat.hbm.xml`, `Dog.hbm.xml`, or if using inheritance, `Animal.hbm.xml`.

#### 5.1.11.3. Key

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:

    <key
            column="columnname"
            on-delete="noaction|cascade"
            property-ref="propertyName"
            not-null="true|false"
            update="true|false"
            unique="true|false"
    />

| `column` (optional): the name of the foreign key column. This can also be specified by nested `<column>` element(s).
| `on-delete` (optional - defaults to `noaction`): specifies whether the foreign key constraint has database-level cascade delete enabled.
| `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.
| `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.
| `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.
| `unique` (optional): specifies that the foreign key should have a unique constraint. This is implied whenever the foreign key is also the primary key.

For systems where delete performance is important, we recommend that all keys should be defined `on-delete="cascade"`. Hibernate uses a database-level `ON CASCADE DELETE` constraint, instead of many individual `DELETE` statements. Be aware that this feature bypasses Hibernate's usual optimistic locking strategy for versioned data.

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 must declare the key column using `<key not-null="true">`.

#### 5.1.11.4. Import

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 `auto-import="true"`. You can also import classes and interfaces that are not explicitly mapped:

    <import class="java.lang.Object" rename="Universe"/>

    <import
            class="ClassName"
            rename="ShortName"
    />

| `class`: the fully qualified class name of any Java class.
| `rename` (optional - defaults to the unqualified class name): a name that can be used in the query language.

## Note

This feature is unique to hbm.xml and is not supported in annotations.

#### 5.1.11.5. Column and formula elements

Mapping elements which accept a `column` attribute will alternatively accept a `<column>` subelement. Likewise, `<formula>` is an alternative to the `formula` attribute. For example:

    <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"/>

    <formula>SQL expression</formula>

Most of the attributes on `column` provide a means of tailoring the DDL during automatic schema generation. The `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 column read and write expressions.

The `column` and `formula` elements can even be combined within the same property or association mapping to express, for example, exotic join conditions.

    <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>

## 5.2. Hibernate types

### 5.2.1. Entities and values

In relation to the persistence service, Java language-level objects are classified into two groups:

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 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.

An entity's persistent state consists of references to other entities and instances of 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, 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.

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 component is a user-defined class with value semantics. A Java property of type `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.

We will revisit both concepts throughout this reference guide.

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, `<class>`, `<subclass>` and so on are used. For value types we use `<property>`, `<component>`etc., that usually have a `type` attribute. The value of this attribute is the name of a Hibernate 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.

With the exception of collections, all built-in Hibernate types support null semantics.

### 5.2.2. Basic value types

The built-in basic mapping types can be roughly categorized into the following:

`integer, long, short, float, double, character, byte, boolean, yes_no, true_false`

  Type mappings from Java primitives or wrapper classes to appropriate (vendor-specific) SQL column types. `boolean, yes_no` and `true_false` are all alternative encodings for a Java `boolean` or `java.lang.Boolean`.

`string`

  A type mapping from `java.lang.String` to `VARCHAR` (or Oracle `VARCHAR2`).

`date, time, timestamp`

  Type mappings from `java.util.Date` and its subclasses to SQL types `DATE`, `TIME` and `TIMESTAMP` (or equivalent).

`calendar, calendar_date`

  Type mappings from `java.util.Calendar` to SQL types `TIMESTAMP` and `DATE` (or equivalent).

`big_decimal, big_integer`

  Type mappings from `java.math.BigDecimal` and `java.math.BigInteger` to `NUMERIC` (or Oracle `NUMBER`).

`locale, timezone, currency`

  Type mappings from `java.util.Locale`, `java.util.TimeZone` and `java.util.Currency` to `VARCHAR` (or Oracle `VARCHAR2`). Instances of `Locale` and `Currency` are mapped to their ISO codes. Instances of `TimeZone` are mapped to their `ID`.

`class`

  A type mapping from `java.lang.Class` to `VARCHAR` (or Oracle `VARCHAR2`). A `Class` is mapped to its fully qualified name.

`binary`

  Maps byte arrays to an appropriate SQL binary type.

`text`

  Maps long Java strings to a SQL `LONGVARCHAR` or `TEXT` type.

`image`

  Maps long byte arrays to a SQL `LONGVARBINARY`.

`serializable`

  Maps serializable Java types to an appropriate SQL binary type. You can also indicate the Hibernate type `serializable` with the name of a serializable Java class or interface that does not default to a basic type.

`clob, blob`

  Type mappings for the JDBC classes `java.sql.Clob` and `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.

`materialized_clob`

  Maps long Java strings to a SQL `CLOB` type. When read, the `CLOB` value is immediately materialized into a Java string. Some drivers require the `CLOB` value to be read within a transaction. Once materialized, the Java string is available outside of the transaction.

`materialized_blob`

  Maps long Java byte arrays to a SQL `BLOB` type. When read, the `BLOB` value is immediately materialized into a byte array. Some drivers require the `BLOB` value to be read within a transaction. Once materialized, the byte array is available outside of the transaction.

`imm_date, imm_time, imm_timestamp, imm_calendar, imm_calendar_date, imm_serializable, imm_binary`

  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 `Date.setTime()` for an instance mapped as `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.

Unique identifiers of entities and collections can be of any basic type except `binary`, `blob` and `clob`. Composite identifiers are also allowed. See below for more information.

The basic value types have corresponding `Type` constants defined on `org.hibernate.Hibernate`. For example, `Hibernate.STRING` represents the `string` type.

### 5.2.3. Custom value types

It is relatively easy for developers to create their own value types. For example, you might want to persist properties of type `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 `getName()`/`setName()` of type `java.lang.String` that is persisted to the columns `FIRST_NAME`, `INITIAL`, `SURNAME`.

To implement a custom type, implement either `org.hibernate.UserType` or `org.hibernate.CompositeUserType` and declare properties using the fully qualified classname of the type. View `org.hibernate.test.DoubleStringType` to see the kind of things that are possible.

    <property name="twoStrings" type="org.hibernate.test.DoubleStringType">
        <column name="first_string"/>
        <column name="second_string"/>
    </property>

Notice the use of `<column>` tags to map a property to multiple columns.

The `CompositeUserType`, `EnhancedUserType`, `UserCollectionType`, and `UserVersionType` interfaces provide support for more specialized uses.

You can even supply parameters to a `UserType` in the mapping file. To do this, your `UserType` must implement the `org.hibernate.usertype.ParameterizedType` interface. To supply parameters to your custom type, you can use the `<type>` element in your mapping files.

    <property name="priority">
        <type name="com.mycompany.usertypes.DefaultValueIntegerType">
            <param name="default">0</param>
        </type>
    </property>

The `UserType` can now retrieve the value for the parameter named `default` from the `Properties` object passed to it.

If you regularly use a certain `UserType`, it is useful to define a shorter name for it. You can do this using the `<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.

    <typedef class="com.mycompany.usertypes.DefaultValueIntegerType" name="default_zero">
        <param name="default">0</param>
    </typedef>

    <property name="priority" type="default_zero"/>

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.

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 `MonetaryAmount` class is a good candidate for a `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.

## 5.3. Mapping a class more than once

It is possible to provide more than one mapping for a particular persistent class. In this case, you must specify an entity name 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.

    <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>

Associations are now specified using `entity-name` instead of `class`.

## Note

This feature is not supported in Annotations

## 5.4. SQL quoted identifiers

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 `Dialect`. This is usually double quotes, but the SQL Server uses brackets and MySQL uses backticks.

    @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>

## 5.5. Generated properties

Generated properties are properties that have their values generated by the database. Typically, Hibernate applications needed to `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.

Properties marked as generated must additionally be non-insertable and non-updateable. Only versions, timestamps, and simple properties, can be marked as generated.

`never` (the default): the given property value is not generated within the database.

`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 version and timestamp properties can be marked as generated, this option is not available.

`always`: the property value is generated both on insert and on update.

To mark a property as generated, use `@Generated`.

## 5.6. Column transformers: read and write expressions

Hibernate allows you to customize the SQL it uses to read and write the values of columns mapped to simple properties. For example, if your database provides a set of data encryption functions, you can invoke them for individual columns like this:

    @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;
    }

or in XML

    <property name="creditCardNumber">
            <column
              name="credit_card_num"
              read="decrypt(credit_card_num)"
              write="encrypt(?)"/>
    </property>

## Note

You can use the plural form `@ColumnTransformers` if more than one columns need to define either of these rules.

If a property uses more that one column, you must use the `forColumn` attribute to specify which column, the expressions are targeting.

    @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;
    }

Hibernate applies the custom expressions automatically whenever the property is referenced in a query. This functionality is similar to a derived-property `formula` with two differences:

- The property is backed by one or more columns that are exported as part of automatic schema generation.

- The property is read-write, not read-only.

The `write` expression, if specified, must contain exactly one '?' placeholder for the value.

## 5.7. Auxiliary database objects

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 `java.sql.Statement.execute()` method is valid (for example, ALTERs, INSERTS, etc.). There are essentially two modes for defining auxiliary database objects:

The first mode is to explicitly list the CREATE and DROP commands in the mapping file:

    <hibernate-mapping>
        ...
        <database-object>
            <create>CREATE TRIGGER my_trigger ...</create>
            <drop>DROP TRIGGER my_trigger</drop>
        </database-object>
    </hibernate-mapping>

The second mode is to supply a custom class that constructs the CREATE and DROP commands. This custom class must implement the `org.hibernate.mapping.AuxiliaryDatabaseObject` interface.

    <hibernate-mapping>
        ...
        <database-object>
            <definition class="MyTriggerDefinition"/>
        </database-object>
    </hibernate-mapping>

Additionally, these database objects can be optionally scoped so that they only apply when certain dialects are used.

    <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>

## Note

This feature is not supported in Annotations

- PrevChapter 4. Persistent Classes
- Up
- Home
- NextChapter 6. Types