Hibernate.orgCommunity Documentation
3.5.6-Final
Copyright © 2004 Red Hat Inc. and the various authors
September 15, 2010
Hibernate, like all other object/relational mapping tools, requires metadata that governs the transformation of data from one representation to the other. Hibernate Annotations provides annotation-based mapping metadata.
The JPA specification recognizes the interest and the success of the transparent object/relational mapping paradigm. It standardizes the basic APIs and the metadata needed for any object/relational persistence mechanism. Hibernate EntityManager implements the programming interfaces and lifecycle rules as defined by the JPA persistence specification and together with Hibernate Annotations offers a complete (and standalone) JPA persistence solution on top of the mature Hibernate Core. You may use a combination of all three together, annotations without JPA programming interfaces and lifecycle, or even pure native Hibernate Core, depending on the business and technical needs of your project. At all time you can fall back to Hibernate native APIs, or if required, even to native JDBC and SQL.
This release of Hibernate Annotations is based on the final release of the JPA 2 specification (aka JSR-317) and supports all its features (including the optional ones). Hibernate specific features and extensions are also available through unstandardized, Hibernate specific annotations.
If you are moving from previous Hibernate Annotations versions, please have a look at Java Persistence migration guide.
Make sure you have JDK 5.0 or above installed.
Download and unpack the Hibernate Core distribution from the Hibernate website. Hibernate 3.5 and onward contains Hibernate Annotations.
Alternatively add the following dependency in your dependency manager (like Maven or Ivy). Here is an example
<project ...>
...
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>${hibernate-core-version}</version>
</dependency>
</dependencies>
</project>
First, set up your classpath (after you have created a new project in your favorite IDE):
Copy hibernate3.jar and the required 3rd
          party libraries available in
          lib/required.
Copy
          lib/jpa/hibernate-jpa-2.0-api-1.0.0.Final.jar
          to your classpath as well.
Alternatively, import your pom.xml in your favorite IDE and let the dependencies be resolved automatically,
This is the JAR containing the JPA 2.0 API, it is fully compliant with the spec and passed the TCK signature test. You typically don't need it when you deploy your application in a Java EE 6 application server (like JBoss AS 6 for example).
We recommend you use Hibernate Validator and the
    Bean Validation specification capabilities as its integration with Java
    Persistence 2 has been standardized. Download Hibernate Validator 4 or
    above from the Hibernate website and add
    hibernate-validator.jar and
    validation-api.jar in your classpath. Alternatively
    add the following dependency in your pom.xml.
<project>
...
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator-version}</version>
</dependency>
...
</dependencies>
...
</project>
If you wish to use Hibernate Search, download it
    from the Hibernate website and add
    hibernate-search.jar and its dependencies in your
    classpath. Alternatively add the following dependency in your
    pom.xml.
<project>
...
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search</artifactId>
<version>${hibernate-search-version}</version>
</dependency>
...
</dependencies>
...
</project>
We recommend you use the JPA 2 APIs to bootstrap Hibernate (see the Hibernate EntityManager documentation for more information). If you use Hibernate Core and its native APIs read on.
If you boot Hibernate yourself, make sure to use the
    AnnotationConfiguration class instead of the
    Configuration class. Here is an example using the
    (legacy) HibernateUtil approach:
package hello;
import org.hibernate.*;
import org.hibernate.cfg.*;
import test.*;
import test.animals.Dog;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory = new AnnotationConfiguration()
.configure().buildSessionFactory();
} catch (Throwable ex) {
// Log exception!
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession()
throws HibernateException {
return sessionFactory.openSession();
}
}
Interesting here is the use of
    AnnotationConfiguration. The packages and annotated
    classes are declared in your regular XML configuration file (usually
    hibernate.cfg.xml). Here is the equivalent of the
    above declaration:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping package="test.animals"/>
<mapping class="test.Flight"/>
<mapping class="test.Sky"/>
<mapping class="test.Person"/>
<mapping class="test.animals.Dog"/>
<mapping resource="test/animals/orm.xml"/>
</session-factory>
</hibernate-configuration>
Note that you can mix the legacy hbm.xml use and the annotation approach. The resource element can be either an hbm file or an EJB3 XML deployment descriptor. The distinction is transparent for your configuration process.
Alternatively, you can define the annotated classes and packages using the programmatic API
sessionFactory = new AnnotationConfiguration() .addPackage("test.animals") //the fully qualified package name .addAnnotatedClass(Flight.class) .addAnnotatedClass(Sky.class) .addAnnotatedClass(Person.class) .addAnnotatedClass(Dog.class) .addResource("test/animals/orm.xml")
.configure()
.buildSessionFactory();
There is no other difference in the way you use Hibernate APIs with
    annotations, except for this startup routine change or in the
    configuration file. You can use your favorite configuration method for
    other properties ( hibernate.properties,
    hibernate.cfg.xml, programmatic APIs, etc).
You can mix annotated persistent classes and classic
      hbm.cfg.xml declarations with the same
      SessionFactory. You can however not declare a
      class several times (whether annotated or through hbm.xml). You cannot
      mix configuration strategies (hbm vs annotations) in an entity hierarchy
      either.
To ease the migration process from hbm files to annotations, the
    configuration mechanism detects the mapping duplication between
    annotations and hbm files. HBM files are then prioritized over annotated
    metadata on a class to class basis. You can change the priority using
    hibernate.mapping.precedence property. The default is
    hbm, class, changing it to class,
    hbm will prioritize the annotated classes over hbm files when a
    conflict occurs.
On top of the Hibernate Core properties, Hibernate Annotations reacts to the following one.
Table 1.1. Hibernate Annotations specific properties
| Property | Function | 
|---|---|
hibernate.cache.default_cache_concurrency_strategy | Setting used to give the name of the default
                | 
hibernate.id.new_generator_mappings | true or false. Setting which indicates whether or
              not the new   | 
We recommend all new projects to use
        hibernate.id.new_generator_mappings=true as the new
        generators are more efficient and closer to the JPA 2 specification
        semantic. However they are not backward compatible with existing
        databases (if a sequence or a table is used for id generation).
Hibernate Annotations utilizes Simple Logging Facade for Java (SLF4J)
    in order to log various system events. SLF4J can direct your logging
    output to several logging frameworks (NOP, Simple, log4j version 1.2, JDK
    1.4 logging, JCL or logback) depending on your chosen binding. In order to
    setup logging properly you will need slf4j-api.jar in
    your classpath together with the jar file for your preferred binding -
    slf4j-log4j12.jar in the case of Log4J. See the SLF4J
    documentation for more
    detail.
The logging categories interesting for Hibernate Annotations are:
Table 1.2. Hibernate Annotations Log Categories
| Category | Function | 
|---|---|
| org.hibernate.cfg | Log all configuration related events (not only annotations). | 
For further category configuration refer to the Logging in the Hibernate Core documentation.
This section explains how to describe persistence mappings using Java Persistence 2.0 annotations as well as Hibernate-specific annotation extensions.
JPA entities are plain POJOs. Actually, they are Hibernate persistent entities. Their mappings are defined through JDK 5.0 annotations instead of hbm.xml files. A JPA 2 XML descriptor syntax for overriding is defined as well). Annotations can be 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. You favorite IDE can auto-complete annotations and their
    attributes for you (even without a specific "JPA" module, since JPA
    annotations are plain JDK 5 annotations).
A good an complete set of working examples can be found in the Hibernate Annotations test suite itself: most of the unit tests have been designed to represent a concrete example and be a source of inspiration for you. You can get the test suite sources in the distribution.
Every persistent POJO class is an entity and is declared using the
      @Entity annotation (at the class level):
@Entity
public class Flight implements Serializable {
Long id;
@Id
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
}
@Entity declares the class as an entity (i.e. a
      persistent POJO class), @Id declares the identifier
      property of this entity. The other mapping declarations are implicit.
      The class Flight is mapped to the Flight table, using the column id as
      its primary key column.
The concept of configuration by exception is central to the JPA specification.
Depending on whether you annotate fields or methods, the access
      type used by Hibernate will be field or
      property. The EJB3 spec requires that you declare
      annotations on the element type that will be accessed, i.e. the getter
      method if you use property access, the field if you
      use field access. Mixing annotations in both fields
      and methods should be avoided. Hibernate will guess the access type from
      the position of @Id or
      @EmbeddedId.
@Table is set at the class level; it allows
        you to define the table, catalog, and schema names for your entity
        mapping. If no @Table is defined the default values
        are used: the unqualified class name of the entity.
@Entity
@Table(name="tbl_sky")
public class Sky implements Serializable {
...
}
The @Table element contains a
        schema and catalog attributes,
        if they need to be defined. You can also define unique constraints to
        the table using the @UniqueConstraint annotation in
        conjunction with @Table (for a unique constraint
        bound to a single column, it is recommended to use the
        @Column.unique approach (refer to
        @Column for more information).
@Table(name="tbl_sky",
uniqueConstraints = {@UniqueConstraint(columnNames={"month", "day"})}
)
A unique constraint is applied to the tuple month, day. Note
        that the columnNames array refers to the logical
        column names.
The logical column name is defined by the Hibernate
        NamingStrategy implementation. The default JPA
        naming strategy uses the physical column name as the logical column
        name but it could be different if for example you append fld_ to all
        your columns using a custom NamingStrategy
        implementation. Note that the logical column name is not necessarily
        equals to the property name esp when the column name is explicitly
        set. Unless you override the NamingStrategy,
        you shouldn't worry about that.
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 (the recommended solution)
        or a timestamp. 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.
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:
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 entity
        manager. 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).
To enable property level lazy fetching, your classes have to be instrumented: bytecode is added to the original class to enable such feature, please refer to the Hibernate reference documentation. If your classes are not instrumented, property level lazy loading is silently ignored.
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 support 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.
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.
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.
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.
The column(s) used for a property mapping can be defined using
        the @Column annotation. Use it to override default
        values (see the EJB3 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="colu
mnName";
    boolean un
ique() default false;
    boolean nu
llable() default true;
    boolean in
sertable() default true;
    boolean up
datable() default true;
    String col
umnDefinition() default "";
    String tab
le() default "";
    int length
() default 255;
    int precis
ion() default 0; // decimal precision
    int scale(
) default 0; // decimal scale
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
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 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
The @Id annotation lets you define which
      property is the identifier of your entity. This property can be set by
      the application itself or be generated by Hibernate (preferred). You can
      define the identifier generation strategy thanks to the
      @GeneratedValue annotation.
JPA defines five types of identifier generation strategies:
AUTO - either identity column, sequence or table depending on the underlying DB
TABLE - table holding the id
IDENTITY - identity column
SEQUENCE - sequence
identity copy - the identity is copied from another entity
Hibernate provides more id generators than the basic JPA ones. Check Section 2.4, “Hibernate Annotation Extensions” for more informations.
The following example shows a sequence generator using the SEQ_STORE configuration (see below)
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
public Integer getId() { ... }
The next example uses the identity generator:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
public Long getId() { ... }
The AUTO generator is the preferred type for
        portable applications (across several DB vendors). The identifier
        generation configuration can be shared for several
        @Id mappings with the generator attribute. There
        are several configurations available through
        @SequenceGenerator and
        @TableGenerator. The scope of a generator 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 at XML level (see Chapter 3, Overriding metadata through XML):
<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 JPA XML (like META-INF/orm.xml) is used
        to define the generators, EMP_GEN and
        SEQ_GEN are application level generators.
        EMP_GEN defines a table based id generator using
        the hilo algorithm with a max_lo of 20. The hi
        value is kept in a table
        "GENERATOR_TABLE". The information is kept in a row
        where pkColumnName "key" is equals to
        pkColumnValue "EMP" and column
        valueColumnName "hi" contains
        the the next high value used.
SEQ_GEN defines a sequence generator using a
        sequence named my_sequence. The allocation size
        used for this sequence based hilo algorithm is 20. Note that this
        version of Hibernate Annotations does not handle
        initialValue in the sequence generator. The default
        allocation size is 50, so if you want to use a sequence and pickup the
        value each time, you must set the allocation size to 1.
We recommend all new projects to use
          hibernate.id.new_generator_mappings=true as the new
          generators are more efficient and closer to the JPA 2 specification
          semantic. However they are not backward compatible with existing
          databases (if a sequence or a table is used for id generation). See
          Section 1.3, “Properties” for more information on how
          to activate them.
Package level definition is not supported by the JPA
          specification. However, you can use the
          @GenericGenerator at the package level (see Section 2.4.2, “Identifier”).
The next example shows the definition of a sequence generator in a class scope:
@Entity
@javax.persistence.SequenceGenerator(
name="SEQ_STORE",
sequenceName="my_sequence"
)
public class Store implements Serializable {
private Long id;
@Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")
public Long getId() { return id; }
}
This class will use a sequence named my_sequence and the SEQ_STORE generator is not visible in other classes. Note that you can check the Hibernate Annotations tests in the org.hibernate.test.annotations.id package for more examples.
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;
}
If you are interested in more examples of "derived identities", the JPA 2 specification has a great set of them in chapter 2.4.1.3.
But an identifier does not have to be a single property, it can be composed of several properties.
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.
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;
}
@Entity
class User {
@EmbeddedId UserId id;
Integer age;
}
@Embeddable
class UserId implements Serializable {
String firstName;
String lastName;
}
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).
In practice, your code only sets the
          Customer.user property and the user id value is
          copied by Hibernate into the CustomerId.userId
          property.
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;
}
@Entity
class User {
@EmbeddedId UserId id;
Integer age;
}
@Embeddable
class UserId implements Serializable {
String firstName;
String lastName;
}
Another, arguably more natural, approach is to place
          @Id on multiple properties of my entity. This
          approach is only supported by Hibernate 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;
}
@Entity
class User {
@EmbeddedId UserId id;
Integer age;
}
@Embeddable
class UserId implements Serializable {
String firstName;
String lastName;
}
In this case Customer being it's own
          identifier representation, it must implement
          Serializable.
@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.
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
class Customer {
@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;
}
@Entity
class User {
@EmbeddedId UserId id;
Integer age;
}
@Embeddable
class UserId implements Serializable {
String firstName;
String lastName;
}
Customer and
          CustomerId do have the same properties
          customerNumber as well as
          user.
While not JPA standard, Hibernate let's you declare the
          vanilla associated property in the
          @IdClass.
@Entity
class Customer {
@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;
}
@Entity
class User {
@EmbeddedId UserId id;
Integer age;
}
@Embeddable
class UserId implements Serializable {
String firstName;
String lastName;
}
Hibernate supports the automatic generation of some of the
          identifier properties. Simply use the
          @GeneratedValue annotation on one or several
          id properties.
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.
EJB3 supports the three types of inheritance:
Table per Class Strategy: the <union-class> element in Hibernate
Single Table per Class Hierarchy Strategy: the <subclass> element in Hibernate
Joined Subclass Strategy: the <joined-subclass> element in Hibernate
The chosen strategy is declared at the class level of the top
      level entity in the hierarchy using the @Inheritance
      annotation.
Annotating interfaces is currently not supported.
This strategy has many drawbacks (esp. with polymorphic queries
        and associations) explained in the JPA spec, the Hibernate reference
        documentation, Hibernate in Action, and many other places. Hibernate
        work around most of them implementing this strategy using SQL
        UNION queries. It is commonly used for the top level of an
        inheritance hierarchy:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Flight implements Serializable { ... }
This strategy supports one-to-many associations provided that
        they are bidirectional. This strategy does not support the
        IDENTITY generator strategy: the id has to be
        shared across several tables. Consequently, when using this strategy,
        you should not use AUTO nor
        IDENTITY.
All properties of all super- and subclasses are mapped into the same table, instances are distinguished by a special discriminator column:
@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 { ... }
Plane is the superclass, it defines the
        inheritance strategy InheritanceType.SINGLE_TABLE.
        It also defines the discriminator column through the
        @DiscriminatorColumn annotation, a discriminator
        column can also define the discriminator type. Finally, the
        @DiscriminatorValue annotation defines the value
        used to differentiate a class in the hierarchy. All of these
        attributes have sensible default values. The default name of the
        discriminator column is DTYPE. The default
        discriminator value is the entity name (as defined in
        @Entity.name) for DiscriminatorType.STRING.
        A320 is a subclass; you only have to define
        discriminator value if you don't want to use the default value. The
        strategy and the discriminator type are implicit.
@Inheritance and
        @DiscriminatorColumn should only be defined at the
        top of the entity hierarchy.
The @PrimaryKeyJoinColumn and
        @PrimaryKeyJoinColumns annotations define the
        primary key(s) of the joined subclass table:
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Boat implements Serializable { ... }
@Entity
public class Ferry extends Boat { ... }
@Entity
@PrimaryKeyJoinColumn(name="BOAT_ID")
public class AmericaCupClass extends Boat { ... }
All of the above entities use the JOINED
        strategy, the Ferry table is joined with the
        Boat table using the same primary key names. The
        AmericaCupClass table is joined with
        Boat using the join condition Boat.id =
        AmericaCupClass.BOAT_ID.
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.
Properties from superclasses not mapped as
          @MappedSuperclass are ignored.
The default access type (field or methods) is used, unless you
          use the @Access annotation.
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)
It is allowed to mark a class as
          @MappedSuperclass in the middle of the mapped
          inheritance hierarchy.
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.
You can associate entities through a one-to-one relationship
        using @OneToOne. There are three cases for
        one-to-one associations: either the associated entities share the same
        primary keys values, a foreign key is held by one of the entities
        (note that this FK column in the database should be constrained unique
        to simulate one-to-one multiplicity), or a association table is used
        to store the link between the 2 entities (a unique constraint has to
        be defined on each fk to ensure the one to one multiplicity).
First, we map a real one-to-one association using shared primary keys:
@Entity
public class Body {
@Id
public Long getId() { return id; }
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Heart getHeart() {
return heart;
}
...
}
@Entity
public class Heart {
@Id
public Long getId() { ...}
}
The @PrimaryKeyJoinColumn annotation does say
        that the primary key of the entity is used as the foreign key value to
        the associated entity.
In the following example, the associated entities are linked through an explicit foreign key column:
@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="passport_fk")
public Passport getPassport() {
...
}
@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
...
}
A Customer is linked to a
        Passport, with a foreign key column named
        passport_fk in the Customer
        table. The join column is declared with the
        @JoinColumn annotation which looks like the
        @Column annotation. It has one more parameters
        named referencedColumnName. This parameter declares
        the column in the targeted entity that will be used to the join. Note
        that when using
         to a non
        primary key column, the associated class has to be
        referencedColumnNameSerializable. Also note that the
         to a non
        primary key column has to be mapped to a property having a single
        column (other cases might not work).referencedColumnName
The association may be bidirectional. In a bidirectional
        relationship, one of the sides (and only one) has to be the owner: the
        owner is responsible for the association column(s) update. To declare
        a side as not responsible for the relationship,
        the attribute mappedBy is used.
        mappedBy refers to the property name of the
        association on the owner side. In our case, this is
        passport. As you can see, you don't have to (must
        not) declare the join column since it has already been declared on the
        owners side.
If no @JoinColumn is declared on the owner
        side, the defaults apply. A join column(s) will be created in the
        owner table and its name will be the concatenation of the name of the
        relationship in the owner side, _ (underscore), and
        the name of the primary key column(s) in the owned side. In this
        example passport_id because the property name is
        passport and the column id of Passport
        is id.
The third possibility (using an association table) is quite exotic.
@Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name = "CustomerPassports",
joinColumns = @JoinColumn(name="customer_fk"),
inverseJoinColumns = @JoinColumn(name="passport_fk")
)
public Passport getPassport() {
...
}
@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {
...
}
A Customer is linked to a
        Passport through a association table named
        CustomerPassports ; this association table has a
        foreign key column named passport_fk pointing to
        the Passport table (materialized by the
        inverseJoinColumn, and a foreign key column named
        customer_fk pointing to the
        Customer table materialized by the
        joinColumns attribute.
You must declare the join table name and the join columns explicitly in such a mapping.
Many-to-one associations are declared at the property level with
        the annotation @ManyToOne:
@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 like in one to one, 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.
@ManyToOne has 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.
@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 many-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;
}
...
}
You can map Collection,
        List, Map and
        Set pointing to associated entities as
        one-to-many or many-to-many associations using the
        @OneToMany or
        @ManyToMany annotation respectively. If the
        collection is of a basic type or of an embeddable type, use
        @ElementCollection. We will describe that in
        more detail in the following subsections.
One-to-many associations are declared at the property level
          with the annotation @OneToMany. One to many
          associations may be bidirectional.
Since many to one are (almost) always the owner side of a
            bidirectional relationship in the JPA spec, the one to many
            association is annotated by
            @OneToMany(mappedBy=...)
@Entity
public class Troop {
@OneToMany(mappedBy="troop")
public Set<Soldier> getSoldiers() {
...
}
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk")
public Troop getTroop() {
...
}
Troop has a bidirectional one to many
            relationship with Soldier through the
            troop property. You don't have to (must not)
            define any physical mapping in the mappedBy
            side.
To map a bidirectional one to many, with the one-to-many
            side as the owning side, you have to remove the
            mappedBy element and set the many to one
            @JoinColumn as insertable and updatable to
            false. This solution is not optimized and will produce some
            additional UPDATE statements.
@Entity
public class Troop {
@OneToMany
@JoinColumn(name="troop_fk") //we need to duplicate the physical information
public Set<Soldier> getSoldiers() {
...
}
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk", insertable=false, updatable=false)
public Troop getTroop() {
...
}
A unidirectional one to many using a foreign key column in
            the owned entity is not that common and not really recommended. We
            strongly advise you to use a join table for this kind of
            association (as explained in the next section). This kind of
            association is described through a
            @JoinColumn
@Entity
public class Customer implements Serializable {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
public Set<Ticket> getTickets() {
...
}
@Entity
public class Ticket implements Serializable {
... //no bidir
}
Customer describes a unidirectional
            relationship with Ticket using the join column
            CUST_ID.
A unidirectional one to many with join table is much
            preferred. This association is described through an
            @JoinTable.
@Entity
public class Trainer {
@OneToMany
@JoinTable(
name="TrainedMonkeys",
joinColumns = @JoinColumn( name="trainer_id"),
inverseJoinColumns = @JoinColumn( name="monkey_id")
)
public Set<Monkey> getTrainedMonkeys() {
...
}
@Entity
public class Monkey {
... //no bidir
}
Trainer describes a unidirectional
            relationship with Monkey using the join
            table TrainedMonkeys, with a foreign key
            trainer_id to Trainer
            (joinColumns) and a foreign key
            monkey_id to Monkey
            (inversejoinColumns).
Without describing any physical mapping, a unidirectional one to many with join table is used. The table name is the concatenation of the owner table name, _, and the other side table name. The foreign key name(s) referencing the owner table is the concatenation of the owner table, _, and the owner primary key column(s) name. The foreign key name(s) referencing the other side is the concatenation of the owner property name, _, and the other side primary key column(s) name. A unique constraint is added to the foreign key referencing the other side table to reflect the one to many.
@Entity
public class Trainer {
@OneToMany
public Set<Tiger> getTrainedTigers() {
...
}
@Entity
public class Tiger {
... //no bidir
}
Trainer describes a unidirectional
            relationship with Tiger using the join
            table Trainer_Tiger, with a foreign key
            trainer_id to Trainer (table
            name, _, trainer id) and a foreign key
            trainedTigers_id to Monkey
            (property name, _, Tiger primary column).
A many-to-many association is defined logically using the
            @ManyToMany annotation. You also have to
            describe the association table and the join conditions using the
            @JoinTable annotation. If the association is
            bidirectional, one side has to be the owner and one side has to be
            the inverse end (ie. it will be ignored when updating the
            relationship values in the association table):
@Entity
public class Employer implements Serializable {
@ManyToMany(
targetEntity=org.hibernate.test.metadata.manytomany.Employee.class,
cascade={CascadeType.PERSIST, CascadeType.MERGE}
)
@JoinTable(
name="EMPLOYER_EMPLOYEE",
joinColumns=@JoinColumn(name="EMPER_ID"),
inverseJoinColumns=@JoinColumn(name="EMPEE_ID")
)
public Collection getEmployees() {
return employees;
}
...
}
@Entity
public class Employee implements Serializable {
@ManyToMany(
cascade = {CascadeType.PERSIST, CascadeType.MERGE},
mappedBy = "employees",
targetEntity = Employer.class
)
public Collection getEmployers() {
return employers;
}
}
We've already shown the many declarations and the detailed
            attributes for associations. We'll go deeper in the
            @JoinTable description, it defines a
            name, an array of join columns (an array in
            annotation is defined using { A, B, C }), and an array of inverse
            join columns. The latter ones are the columns of the association
            table which refer to the Employee primary
            key (the "other side").
As seen previously, the other side don't have to (must not)
            describe the physical mapping: a simple
            mappedBy argument containing the owner side
            property name bind the two.
As any other annotations, most values are guessed in a many to many relationship. Without describing any physical mapping in a unidirectional many to many the following rules applied. The table name is the concatenation of the owner table name, _ and the other side table name. The foreign key name(s) referencing the owner table is the concatenation of the owner table name, _ and the owner primary key column(s). The foreign key name(s) referencing the other side is the concatenation of the owner property name, _, and the other side primary key column(s). These are the same rules used for a unidirectional one to many relationship.
@Entity
public class Store {
@ManyToMany(cascade = CascadeType.PERSIST)
public Set<City> getImplantedIn() {
...
}
}
@Entity
public class City {
... //no bidirectional relationship
}
A Store_City is used as the join table.
            The Store_id column is a foreign key to the
            Store table. The
            implantedIn_id column is a foreign key to the
            City table.
Without describing any physical mapping in a bidirectional many to many the following rules applied. The table name is the concatenation of the owner table name, _ and the other side table name. The foreign key name(s) referencing the owner table is the concatenation of the other side property name, _, and the owner primary key column(s). The foreign key name(s) referencing the other side is the concatenation of the owner property name, _, and the other side primary key column(s). These are the same rules used for a unidirectional one to many relationship.
@Entity
public class Store {
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
public Set<Customer> getCustomers() {
...
}
}
@Entity
public class Customer {
@ManyToMany(mappedBy="customers")
public Set<Store> getStores() {
...
}
}
A Store_Customer is used as the join
            table. The stores_id column is a foreign key to
            the Store table. The
            customers_id column is a foreign key to the
            Customer table.
In some simple situation, do don't need to associate two
          entities but simply create a collection of basic types or embeddable
          objects. Use the @ElementCollection in this
          case.
@Entity
public class User {
[...]
public String getLastname() { ...}
@ElementCollection
@CollectionTable(name="Nicknames", joinColumns=@JoinColumn(name="user_id"))
@Column(name="nickname")
public Set<String> getNicknames() { ... }
}
The collection table holding the collection data is set using
          the @CollectionTable annotation. If omitted
          the collection table name default to the concatenation of the name
          of the containing entity and the name of the collection attribute,
          separated by an underscore: in our example, it would be
          User_nicknames.
The column holding the basic type is set using the
          @Column annotation. If omitted, the column
          name defaults to the property name: in our example, it would be
          nicknames.
But you are not limited to basic types, the collection type
          can be any embeddable object. To override the columns of the
          embeddable object in the collection table, use the
          @AttributeOverride annotation.
@Entity
public class User {
[...]
public String getLastname() { ...}
@ElementCollection
@CollectionTable(name="Addresses", joinColumns=@JoinColumn(name="user_id"))
@AttributeOverrides({
@AttributeOverride(name="street1", column=@Column(name="fld_street"))
})
public Set<Address> getAddresses() { ... }
}
@Embeddable
public class Address {
public String getStreet1() {...}
[...]
}
Such an embeddable object cannot contains a collection itself.
in @AttributeOverride, you must use
            the value. prefix to override properties of the
            embeddable object used in the map value and the
            key. prefix to override properties of the
            embeddable object used in the map key.
@Entity
public class User {
@ElementCollection
@AttributeOverrides({
@AttributeOverride(name="key.street1", column=@Column(name="fld_street")),
@AttributeOverride(name="value.stars", column=@Column(name="fld_note"))
})
public Map<Address,Rating> getFavHomes() { ... }
We recommend you to migrate from
            @org.hibernate.annotations.CollectionOfElements
            to the new @ElementCollection
            annotation.
Lists can be mapped in two different ways:
as ordered lists, the order is not materialized in the database
as indexed lists, the order is materialized in the database
To order lists in memory, add
          @javax.persistence.OrderBy to your property. This
          annotation takes into parameter a list of comma separated properties
          (of the target entity) and order the collection accordingly (eg
          firstname asc, age desc), if the string is empty, the
          collection will be ordered by the primary key of the target
          entity.
@Entity
public class Customer {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
@OneToMany(mappedBy="customer")
@OrderBy("number")
public List<Order> getOrders() { return orders; }
public void setOrders(List<Order> orders) { this.orders = orders; }
private List<Order> orders;
}
@Entity
public class Order {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
public String getNumber() { return number; }
public void setNumber(String number) { this.number = number; }
private String number;
@ManyToOne
public Customer getCustomer() { return customer; }
public void setCustomer(Customer customer) { this.customer = customer; }
private Customer number;
}
-- Table schema
|-------------| |----------|
| Order | | Customer |
|-------------| |----------|
| id | | id |
| number | |----------|
| customer_id |
|-------------|
To store the index value in a dedicated column, use the
          @javax.persistence.OrderColumn annotation on
          your property. This annotations describes the column name and
          attributes of the column keeping the index value. This column is
          hosted on the table containing the association foreign key. If the
          column name is not specified, the default is the name of the
          referencing property, followed by underscore, followed by
          ORDER (in the following example, it would be
          orders_ORDER).
@Entity
public class Customer {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
@OneToMany(mappedBy="customer")
@OrderColumn(name"orders_index")
public List<Order> getOrders() { return orders; }
public void setOrders(List<Order> orders) { this.orders = orders; }
private List<Order> orders;
}
@Entity
public class Order {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
public String getNumber() { return number; }
public void setNumber(String number) { this.number = number; }
private String number;
@ManyToOne
public Customer getCustomer() { return customer; }
public void setCustomer(Customer customer) { this.customer = customer; }
private Customer number;
}
-- Table schema
|--------------| |----------|
| Order | | Customer |
|--------------| |----------|
| id | | id |
| number | |----------|
| customer_id |
| orders_index |
|--------------|
We recommend you to convert
            @org.hibernate.annotations.IndexColumn
            usages to @OrderColumn unless you are
            making use of the base property. The base
            property lets you define the index value of the first element (aka
            as base index). The usual value is 0 or
            1. The default is 0 like in Java.
Likewise, maps can borrow their keys from one of the associated entity properties or have dedicated columns to store an explicit key.
To use one of the target entity property as a key of the map,
          use @MapKey(name="myProperty")
          (myProperty is a property name in the target
          entity). When using @MapKey (without property
          name), the target entity primary key is used. The map key uses the
          same column as the property pointed out: there is no additional
          column defined to hold the map key, and it does make sense since the
          map key actually represent a target property. Be aware that once
          loaded, the key is no longer kept in sync with the property, in
          other words, if you change the property value, the key will not
          change automatically in your Java model.
@Entity
public class Customer {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
@OneToMany(mappedBy="customer")
@MapKey(name"number")
public Map<String,Order> getOrders() { return orders; }
public void setOrders(Map<String,Order> order) { this.orders = orders; }
private Map<String,Order> orders;
}
@Entity
public class Order {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
public String getNumber() { return number; }
public void setNumber(String number) { this.number = number; }
private String number;
@ManyToOne
public Customer getCustomer() { return customer; }
public void setCustomer(Customer customer) { this.customer = customer; }
private Customer number;
}
-- Table schema
|-------------| |----------|
| Order | | Customer |
|-------------| |----------|
| id | | id |
| number | |----------|
| customer_id |
|-------------|
Otherwise, the map key is mapped to a dedicated column or columns. To customize things, use one of the following annotations:
@MapKeyColumn if the map key is a
              basic type, if you don't specify the column name, the name of
              the property followed by underscore followed by
              KEY is used (for example
              orders_KEY).
@MapKeyEnumerated /
              @MapKeyTemporal if the map key type is
              respectively an enum or a Date.
@MapKeyJoinColumn/@MapKeyJoinColumns
              if the map key type is another entity.
@AttributeOverride/@AttributeOverrides
              when the map key is a embeddable object. Use
              key. as a prefix for your embeddable object
              property names.
You can also use @MapKeyClass to define
          the type of the key if you don't use generics (at this stage, you
          should wonder why at this day and age you don't use
          generics).
@Entity
public class Customer {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
@OneToMany @JoinTable(name="Cust_Order")
@MapKeyColumn(name"orders_number")
public Map<String,Order> getOrders() { return orders; }
public void setOrders(Map<String,Order> orders) { this.orders = orders; }
private Map<String,Order> orders;
}
@Entity
public class Order {
@Id @GeneratedValue public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
public String getNumber() { return number; }
public void setNumber(String number) { this.number = number; }
private String number;
@ManyToOne
public Customer getCustomer() { return customer; }
public void setCustomer(Customer customer) { this.customer = customer; }
private Customer number;
}
-- Table schema
|-------------| |----------| |---------------|
| Order | | Customer | | Cust_Order |
|-------------| |----------| |---------------|
| id | | id | | customer_id |
| number | |----------| | order_id |
| customer_id | | orders_number |
|-------------| |---------------|
We recommend you to migrate from
            @org.hibernate.annotations.MapKey /
            @org.hibernate.annotation.MapKeyManyToMany
            to the new standard approach described above.
Let's now explore the various collection semantics based on the mapping you are choosing.
Table 2.1. Collections semantics
| Semantic | java representation | annotations | 
|---|---|---|
| Bag semantic | java.util.List, java.util.Collection | @ElementCollection or @OneToMany or @ManyToMany | 
| Bag semantic with primary key (without the limitations of Bag semantic) | java.util.List, java.util.Collection | (@ElementCollection or @OneToMany or @ManyToMany) and @CollectionId | 
| List semantic | java.util.List | (@ElementCollection or @OneToMany or @ManyToMany) and (@OrderColumn or @org.hibernate.annotations.IndexColumn) | 
| Set semantic | java.util.Set | @ElementCollection or @OneToMany or @ManyToMany | 
| Map semantic | java.util.Map | (@ElementCollection or @OneToMany or @ManyToMany) and ((nothing or @MapKeyJoinColumn/@MapKeyColumn for true map support) OR @javax.persistence.MapKey) | 
Specifically, java.util.List collections without @OrderColumn or @IndexColumn are going to be considered as bags.
More support for collections are available via Hibernate specific extensions (see Section 2.4, “Hibernate Annotation Extensions”).
You probably have noticed the cascade
        attribute taking an array of CascadeType as a
        value. The cascade concept in JPA is very is similar to the transitive
        persistence and cascading of operations in Hibernate, but with
        slightly different semantics and cascading types:
CascadeType.PERSIST: cascades the persist
            (create) operation to associated entities persist() is called or
            if the entity is managed
CascadeType.MERGE: cascades the merge
            operation to associated entities if merge() is called or if the
            entity is managed
CascadeType.REMOVE: cascades the remove
            operation to associated entities if delete() is called
CascadeType.REFRESH: cascades the refresh
            operation to associated entities if refresh() is called
CascadeType.DETACH: cascades the detach
            operation to associated entities if detach() is called
CascadeType.ALL: all of the above
CascadeType.ALL also covers Hibernate specific operations like save-update, lock etc... Check Section 2.4.7, “Cascade” for more information
Please refer to the chapter 6.3 of the JPA specification for more information on cascading and create/merge semantics.
You can also enable the orphan removal semantic. If an entity is
        removed from a @OneToMany collection or an
        associated entity is dereferenced from a
        @OneToOne association, this associated entity
        can be marked for deletion if orphanRemoval is set
        to true. In a way, it means that the associated entity's lifecycle is
        bound to the owning entity just like an embeddable object is.
@Entity class Customer {
@OneToMany(orphanRemoval=true) public Set<Order> getOrders() { return orders; }
public void setOrders(Set<Order> orders) { this.orders = orders; }
private Set<Order> orders;
[...]
}
@Entity class Order { ... }
Customer customer = em.find(Customer.class, 1l);
Order order = em.find(Order.class, 1l);
customer.getOrders().remove(order); //order will be deleted by cascade
You have the ability to either eagerly or lazily fetch
        associated entities. The fetch parameter can be set
        to FetchType.LAZY or
        FetchType.EAGER. EAGER will try
        to use an outer join select to retrieve the associated object, while
        LAZY will only trigger a select when the associated
        object is accessed for the first time. @OneToMany
        and @ManyToMany associations are defaulted to
        LAZY and @OneToOne and
        @ManyToOne are defaulted to
        EAGER. For more information about static fetching,
        check Section 2.4.5.1, “Lazy options and
        fetching modes”.
The recommanded approach is to use LAZY on
        all static fetching definitions and override this choice dynamically
        through JP-QL. JP-QL has a fetch keyword that
        allows you to override laziness when doing a particular query. This is
        very useful to improve performance and is decided on a use case to use
        case basis.
Composite primary keys use a embedded class as the primary key
      representation, so you'd use the @Id and
      @Embeddable annotations. Alternatively, you can use
      the @EmbeddedId annotation. Note that the dependent
      class has to be serializable and implements
      equals()/hashCode().
      You can also use @IdClass. These are more detailed in
      Section 2.2.3, “Mapping identifier properties”.
@Entity
public class RegionalArticle implements Serializable {
@Id
public RegionalArticlePk getPk() { ... }
}
@Embeddable
public class RegionalArticlePk implements Serializable { ... }
or alternatively
@Entity
public class RegionalArticle implements Serializable {
@EmbeddedId
public RegionalArticlePk getPk() { ... }
}
public class RegionalArticlePk implements Serializable { ... }
@Embeddable inherit the access type of its
      owning entity unless @Access is used. Composite
      foreign keys (if not using the default sensitive values) are defined on
      associations using the @JoinColumns element, which is
      basically an array of @JoinColumn. It is considered a
      good practice to express referencedColumnNames
      explicitly. Otherwise, Hibernate will suppose that you use the same
      order of columns as in the primary key declaration.
@Entity
public class Parent implements Serializable {
@Id
public ParentPk id;
public int age;
@OneToMany(cascade=CascadeType.ALL)
@JoinColumns ({
@JoinColumn(name="parentCivility", referencedColumnName = "isMale"),
@JoinColumn(name="parentLastName", referencedColumnName = "lastName"),
@JoinColumn(name="parentFirstName", referencedColumnName = "firstName")
})
public Set<Child> children; //unidirectional
...
}
@Entity
public class Child implements Serializable {
@Id @GeneratedValue
public Integer id;
@ManyToOne
@JoinColumns ({
@JoinColumn(name="parentCivility", referencedColumnName = "isMale"),
@JoinColumn(name="parentLastName", referencedColumnName = "lastName"),
@JoinColumn(name="parentFirstName", referencedColumnName = "firstName")
})
public Parent parent; //unidirectional
}
@Embeddable
public class ParentPk implements Serializable {
String firstName;
String lastName;
...
}
Note the explicit usage of the
      referencedColumnName.
You can map a single entity to 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.
Hibernate offers naturally a first level cache for entities called
      a persistence context via the notion of Session.
      This cache is contextual to the use case at hand. Some entities however
      are shared by many different use cases and are barely changed. You can
      cache these in what is called the second level cache.
By default, entities are not part of the second level cache. While
      we do not recommend that, you can override this by setting the
      shared-cache-mode element in your persistence.xml
      file or by using the javax.persistence.sharedCache.mode
      property. The following values are possible:
ENABLE_SELECTIVE (Default and recommended
          value): entities are not cached unless explicitly marked as
          cacheable.
DISABLE_SELECTIVE: entities are cached
          unless explicitly marked as not cacheable.
ALL: all entities are always cached even if
          marked as non cacheable.
NONE: no entity are cached even if marked
          as cacheable. This option can make sense to disable second-level
          cache altogether.
The cache concurrency strategy used by default can be set with the
      hibernate.cache.default_cache_concurrency_strategy
      property:
read-only
read-write
nonstrict-read-write
transactional
It is recommended to define the cache concurrency strategy per
        entity rather than using a global one. Use the
        @org.hibernate.annotations.Cache annotation for
        that.
@Entity @Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Forest { ... }
Hibernate also let's you cache the content of a collection or the
      identifiers if the collection contains other entities. Use the
      @Cache annotation on the collection
      property.
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public SortedSet<Ticket> getTickets() {
return tickets;
}
@org.hibernate.annotations.Cache defines the
      caching strategy and region of a given second level cache.
@Cache(
    CacheConcu
rrencyStrategy usage();
    String reg
ion() default "";
    String inc
lude() default "all";
)
  | usage: the given cache concurrency strategy (NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL)  | 
  | region (optional): the cache region (default to the fqcn of the class or the fq role name of the collection)  | 
  | 
  | 
While you can write queries in your code, it is considered a good practice to externalize them:
it make developer/DBA communications easier
named queries are pre-compiled by Hibernate at startup time
Unfortunately, you lose the type-safety of queries written using the Criteria API.
You can map JP-QL/HQL queries using annotations.
      @NamedQuery and @NamedQueries can
      be defined at the class level or in a JPA XML deployment descriptor.
      However their definitions are global to the session factory/entity
      manager factory scope. A named query is defined by its name and the
      actual query string.
<entity-mappings>
<named-query name="plane.getAll">
<query>select p from Plane p</query>
</named-query>
...
</entity-mappings>
...
@Entity
@NamedQuery(name="night.moreRecentThan", query="select n from Night n where n.date >= :date")
public class Night {
...
}
public class MyDao {
doStuff() {
Query q = s.getNamedQuery("night.moreRecentThan");
q.setDate( "date", aMonthAgo );
List results = q.list();
...
}
...
}
You can also provide some hints to a query through an array of
      QueryHint through a hints
      attribute.
The available Hibernate hints are
Table 2.2. Query hints
| hint | description | 
|---|---|
| org.hibernate.cacheable | Whether the query should interact with the second level cache (defualt to false) | 
| org.hibernate.cacheRegion | Cache region name (default used otherwise) | 
| org.hibernate.timeout | Query timeout | 
| org.hibernate.fetchSize | resultset fetch size | 
| org.hibernate.flushMode | Flush mode used for this query | 
| org.hibernate.cacheMode | Cache mode used for this query | 
| org.hibernate.readOnly | Entities loaded by this query should be in read only mode or not (default to false) | 
| org.hibernate.comment | Query comment added to the generated SQL | 
You can also define the lock mode by which the returned entities
      should be locked using the lockMode property. This is
      equivalent to the optional lock mode of the entitymanager lookup
      operations.
You can also map a native query (ie a plain SQL query). To achieve
      that, you need to describe the SQL resultset structure using
      @SqlResultSetMapping (or
      @SqlResultSetMappings if you plan to define several
      resulset mappings). Like @NamedQuery, a
      @SqlResultSetMapping can be defined at class level or
      in a JPA XML file. However its scope is global to the
      application.
As we will see, a resultSetMapping parameter is
      defined in @NamedNativeQuery, it represents the name
      of a defined @SqlResultSetMapping. The resultset
      mapping declares the entities retrieved by this native query. Each field
      of the entity is bound to an SQL alias (or column name). All fields of
      the entity including the ones of subclasses and the foreign key columns
      of related entities have to be present in the SQL query. Field
      definitions are optional provided that they map to the same column name
      as the one declared on the class property.
@NamedNativeQuery(name="night&area", query="select night.id nid, night.night_duration, "
+ " night.night_date, area.id aid, night.area_id, area.name "
+ "from Night night, Area area where night.area_id = area.id",
resultSetMapping="joinMapping")
@SqlResultSetMapping(name="joinMapping", entities={
@EntityResult(entityClass=Night.class, fields = {
@FieldResult(name="id", column="nid"),
@FieldResult(name="duration", column="night_duration"),
@FieldResult(name="date", column="night_date"),
@FieldResult(name="area", column="area_id"),
discriminatorColumn="disc"
}),
@EntityResult(entityClass=org.hibernate.test.annotations.query.Area.class, fields = {
@FieldResult(name="id", column="aid"),
@FieldResult(name="name", column="name")
})
}
)
In the above example, the night&area named
      query use the joinMapping result set mapping. This
      mapping returns 2 entities, Night and
      Area, each property is declared and associated to a
      column name, actually the column name retrieved by the query. Let's now
      see an implicit declaration of the property / column.
@Entity
@SqlResultSetMapping(name="implicit",
entities=@EntityResult(entityClass=SpaceShip.class))
@NamedNativeQuery(name="implicitSample",
query="select * from SpaceShip",
resultSetMapping="implicit")
public class SpaceShip {
private String name;
private String model;
private double speed;
@Id
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name="model_txt")
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
}
In this example, we only describe the entity member of the result
      set mapping. The property / column mappings is done using the entity
      mapping values. In this case the model property is
      bound to the model_txt column. If the association to
      a related entity involve a composite primary key, a
      @FieldResult element should be used for each foreign
      key column. The @FieldResult name is composed of the
      property name for the relationship, followed by a dot ("."), followed by
      the name or the field or property of the primary key.
@Entity
@SqlResultSetMapping(name="compositekey",
entities=@EntityResult(entityClass=SpaceShip.class,
fields = {
@FieldResult(name="name", column = "name"),
@FieldResult(name="model", column = "model"),
@FieldResult(name="speed", column = "speed"),
@FieldResult(name="captain.firstname", column = "firstn"),
@FieldResult(name="captain.lastname", column = "lastn"),
@FieldResult(name="dimensions.length", column = "length"),
@FieldResult(name="dimensions.width", column = "width")
}),
columns = { @ColumnResult(name = "surface"),
@ColumnResult(name = "volume") } )
@NamedNativeQuery(name="compositekey",
query="select name, model, speed, lname as lastn, fname as firstn, length, width, length * width as surface from SpaceShip",
resultSetMapping="compositekey")
} )
public class SpaceShip {
private String name;
private String model;
private double speed;
private Captain captain;
private Dimensions dimensions;
@Id
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne(fetch= FetchType.LAZY)
@JoinColumns( {
@JoinColumn(name="fname", referencedColumnName = "firstname"),
@JoinColumn(name="lname", referencedColumnName = "lastname")
} )
public Captain getCaptain() {
return captain;
}
public void setCaptain(Captain captain) {
this.captain = captain;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public Dimensions getDimensions() {
return dimensions;
}
public void setDimensions(Dimensions dimensions) {
this.dimensions = dimensions;
}
}
@Entity
@IdClass(Identity.class)
public class Captain implements Serializable {
private String firstname;
private String lastname;
@Id
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
@Id
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
If you retrieve a single entity and if you use the default
      mapping, you can use the resultClass attribute
      instead of resultSetMapping:
@NamedNativeQuery(name="implicitSample", query="select * from SpaceShip",
resultClass=SpaceShip.class)
public class SpaceShip {
In some of your native queries, you'll have to return scalar
      values, for example when building report queries. You can map them in
      the @SqlResultsetMapping through
      @ColumnResult. You actually can even mix, entities
      and scalar returns in the same native query (this is probably not that
      common though).
@SqlResultSetMapping(name="scalar", columns=@ColumnResult(name="dimension"))
@NamedNativeQuery(name="scalar", query="select length*width as dimension from SpaceShip", resultSetMapping="scalar")
An other query hint specific to native queries has been
      introduced: org.hibernate.callable which can be true
      or false depending on whether the query is a stored procedure or
      not.
Hibernate 3.1 offers a variety of additional annotations that you can mix/match with your EJB 3 entities. They have been designed as a natural extension of EJB3 annotations.
To empower the EJB3 capabilities, hibernate provides specific
    annotations that match hibernate features. The
    org.hibernate.annotations package contains all
    these annotations extensions.
You can fine tune some of the actions done by Hibernate on entities beyond what the EJB3 spec offers.
@org.hibernate.annotations.Entity adds
      additional metadata that may be needed beyond what is defined in the
      standard @Entity 
mutable: whether this entity is mutable or not
dynamicInsert: allow dynamic SQL for inserts
dynamicUpdate: allow dynamic SQL for updates
selectBeforeUpdate: Specifies that Hibernate should never perform an SQL UPDATE unless it is certain that an object is actually modified.
polymorphism: whether the entity polymorphism is of PolymorphismType.IMPLICIT (default) or PolymorphismType.EXPLICIT
optimisticLock: optimistic locking strategy (OptimisticLockType.VERSION, OptimisticLockType.NONE, OptimisticLockType.DIRTY or OptimisticLockType.ALL)
@javax.persistence.Entity is still mandatory, @org.hibernate.annotations.Entity is not a replacement.
Here are some additional Hibernate annotation extensions
@org.hibernate.annotations.BatchSize allows you
      to define the batch size when fetching instances of this entity ( eg.
      @BatchSize(size=4) ). When loading a given entity,
      Hibernate will then load all the uninitialized entities of the same type
      in the persistence context up to the batch size.
@org.hibernate.annotations.Proxy defines the
      laziness attributes of the entity. lazy (default to true) define whether
      the class is lazy or not. proxyClassName is the interface used to
      generate the proxy (default is the class itself).
@org.hibernate.annotations.Where defines an
      optional SQL WHERE clause used when instances of this class is
      retrieved.
@org.hibernate.annotations.Check defines an
      optional check constraints defined in the DDL statetement.
@OnDelete(action=OnDeleteAction.CASCADE) on
      joined subclasses: use a SQL cascade delete on deletion instead of the
      regular Hibernate mechanism.
@Table(appliesTo="tableName", indexes = {
      @Index(name="index1", columnNames={"column1", "column2"} ) } )
      creates the defined indexes on the columns of table
      tableName. This can be applied on the primary table
      or any secondary table. The @Tables annotation allows
      your to apply indexes on different tables. This annotation is expected
      where @javax.persistence.Table or
      @javax.persistence.SecondaryTable(s) occurs.
@org.hibernate.annotations.Table is a
        complement, not a replacement to
        @javax.persistence.Table. Especially, if you want
        to change the default name of a table, you must use
        @javax.persistence.Table, not
        @org.hibernate.annotations.Table.
@org.hibernate.annotations.Table can also be
      used to define the following elements of secondary tables:
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.
@Immutable marks an entity or collection as
      immutable. An immutable entity may not be updated by the application.
      This allows Hibernate to make some minor performance optimizations.
      Updates to an immutable entity will be ignored, but no exception is
      thrown. @Immutable must be used on root entities
      only. @Immutable placed on a collection makes the
      collection immutable, meaning additions and deletions to and from the
      collection are not allowed. A HibernateException is
      thrown in this case.
@Persister lets you define your own custom
      persistence strategy. You may, for example, specify your own subclass of
      org.hibernate.persister.EntityPersister or you
      might even provide a completely new implementation of the interface
      org.hibernate.persister.ClassPersister that
      implements persistence via, for example, stored procedure calls,
      serialization to flat files or LDAP.
@Entity
@BatchSize(size=5)
@org.hibernate.annotations.Entity(
selectBeforeUpdate = true,
dynamicInsert = true, dynamicUpdate = true,
optimisticLock = OptimisticLockType.ALL,
polymorphism = PolymorphismType.EXPLICIT)
@Where(clause="1=1")
@org.hibernate.annotations.Table(name="Forest", indexes = { @Index(name="idx", columnNames = { "name", "length" } ) } )
@Persister(impl=MyEntityPersister.class)
public class Forest { ... }
@Entity
@Inheritance(
strategy=InheritanceType.JOINED
)
public class Vegetable { ... }
@Entity
@OnDelete(action=OnDeleteAction.CASCADE)
public class Carrot extends Vegetable { ... }
Hibernate Annotations goes beyond the Java Persistence specification when defining identifiers.
@org.hibernate.annotations.GenericGenerator
        and @org.hibernate.annotations.GenericGenerators
        allows you to define an Hibernate specific id
        generator.
@Id @GeneratedValue(generator="system-uuid")
@GenericGenerator(name="system-uuid", strategy = "uuid")
public String getId() {
@Id @GeneratedValue(generator="hibseq")
@GenericGenerator(name="hibseq", strategy = "seqhilo",
parameters = {
@Parameter(name="max_lo", value = "5"),
@Parameter(name="sequence", value="heybabyhey")
}
)
public Integer getId() {
strategy is the short name of an Hibernate3
        generator strategy or the fully qualified class name of an
        IdentifierGenerator implementation. You can add
        some parameters through the parameters
        attribute.
Contrary to their standard counterpart,
        @GenericGenerator and
        @GenericGenerators can be used in package level
        annotations, making them application level generators (just like if
        they were in a JPA XML file).
@GenericGenerators(
{
@GenericGenerator(
name="hibseq",
strategy = "seqhilo",
parameters = {
@Parameter(name="max_lo", value = "5"),
@Parameter(name="sequence", value="heybabyhey")
}
),
@GenericGenerator(...)
}
)
package org.hibernate.test.model
While not used as identifier property, some (group of)
        properties represent natural identifier of an entity. This is
        especially true when the schema uses the recommended approach of using
        surrogate primary key even if a natural business key exists. Hibernate
        allows to map such natural properties and reuse them in a
        Criteria query. The natural identifier is
        composed of all the properties marked
        @NaturalId.
@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();
Note that the group of properties representing the natural identifier have to be unique (Hibernate will generate a unique constraint if the database schema is generated).
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.
@org.hibernate.annotations.Type overrides the
        default hibernate type used: this is generally not necessary since the
        type is correctly inferred by Hibernate. Please refer to the Hibernate
        reference guide for more informations on the Hibernate types.
@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.
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;
...
}
You can define an index on a particular column using the
        @Index annotation on a one column property, the
        columnNames attribute will then be ignored
@Column(secondaryTable="Cat1")
@Index(name="story1index")
public String getStoryPart1() {
return storyPart1;
}
When inside an embeddable object, you can define one of the properties as a pointer back to the owner element.
@Entity
public class Person {
@Embeddable public Address address;
...
}
@Embeddable
public class Address {
@Parent public Person owner;
...
}
person == person.address.owner
Some properties are generated at insert or update time by your database. Hibernate can deal with such properties and triggers a subsequent select to read these properties.
@Entity
public class Antenna {
@Id public Integer id;
@Generated(GenerationTime.ALWAYS)
@Column(insertable = false, updatable = false)
public String longitude;
@Generated(GenerationTime.INSERT) @Column(insertable = false)
public String latitude;
}
Annotate your property as @Generated You have
        to make sure your insertability or updatability does not conflict with
        the generation strategy you have chosen. When
        GenerationTime.INSERT is chosen, the property must
        not contains insertable columns, when
        GenerationTime.ALWAYS is chosen, the property must
        not contains insertable nor updatable columns.
@Version properties cannot be
        @Generated(INSERT) by design, it has to be either
        NEVER or ALWAYS.
Sometimes, the type guessed by reflection is not the one you
        want Hibernate to use. This is especially true on components when an
        interface is used. You can use @Target to by pass
        the reflection guessing mechanism (very much like the
        targetEntity attribute available on
        associations.
@Embedded
@Target(OwnerImpl.class)
public Owner getOwner() {
return owner;
}
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.
SINGLE_TABLE is a very powerful strategy but sometimes, and
      especially for legacy systems, you cannot add an additional
      discriminator column. For that purpose Hibernate has introduced the
      notion of discriminator formula:
      @DiscriminatorFormula is a replacement of
      @DiscriminatorColumn and use a SQL fragment as a
      formula for discriminator resolution (no need to have a dedicated
      column).
@Entity
@DiscriminatorFormula("case when forest_type is null then 0 else forest_type end")
public class Forest { ... }
By default, when querying the top entities, Hibernate does not put
      a restriction clause on the discriminator column. This can be
      inconvenient if this column contains values not mapped in your hierarchy
      (through @DiscriminatorValue). To work around that
      you can use @ForceDiscriminator (at the class level,
      next to @DiscriminatorColumn). Hibernate will then
      list the available values when loading the entities.
You can define the foreign key name generated by Hibernate for subclass tables in the JOINED inheritance strategy.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class File { ... }
@Entity
@ForeignKey(name = "FK_DOCU_FILE")
public class Document extends File {
The foreign key from the Document table to the
      File table will be named
      FK_DOCU_FILE.
By default, 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 by Hibernate. 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. This annotation can be used
      on a @OneToOne (with FK),
      @ManyToOne, @OneToMany or
      @ManyToMany association.
@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.
@Entity
public class Child {
...
@ManyToOne
@OnDelete(action=OnDeleteAction.CASCADE)
public Parent getParent() { ... }
...
}
In this case Hibernate generates a cascade delete constraint at the database level.
Foreign key constraints, while generated by Hibernate, have a
      fairly unreadable name. You can override the constraint name by use
      @ForeignKey.
@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
JPA comes with the fetch option to define
        lazy loading and fetching modes, however Hibernate has a much more
        option set in this area. To fine tune the lazy loading and fetching
        strategies, some additional annotations have been introduced:
@LazyToOne: defines the lazyness option
            on @ManyToOne and @OneToOne
            associations. LazyToOneOption can be
            PROXY (ie use a proxy based lazy loading),
            NO_PROXY (use a bytecode enhancement based lazy
            loading - note that build time bytecode processing is necessary)
            and FALSE (association not lazy)
@LazyCollection: defines the lazyness
            option on @ManyToMany and
            @OneToMany associations. LazyCollectionOption
            can be TRUE (the collection is lazy and will be
            loaded when its state is accessed), EXTRA (the
            collection is lazy and all operations will try to avoid the
            collection loading, this is especially useful for huge collections
            when loading all the elements is not necessary) and FALSE
            (association not lazy)
@Fetch: defines the fetching strategy
            used to load the association. FetchMode can be
            SELECT (a select is triggered when the
            association needs to be loaded), SUBSELECT
            (only available for collections, use a subselect strategy - please
            refers to the Hibernate Reference Documentation for more
            information) 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).
The Hibernate annotations overrides the EJB3 fetching options.
Table 2.3. Lazy and fetch options equivalent
| Annotations | Lazy | Fetch | 
|---|---|---|
| @[One|Many]ToOne](fetch=FetchType.LAZY) | @LazyToOne(PROXY) | @Fetch(SELECT) | 
| @[One|Many]ToOne](fetch=FetchType.EAGER) | @LazyToOne(FALSE) | @Fetch(JOIN) | 
| @ManyTo[One|Many](fetch=FetchType.LAZY) | @LazyCollection(TRUE) | @Fetch(SELECT) | 
| @ManyTo[One|Many](fetch=FetchType.EAGER) | @LazyCollection(FALSE) | @Fetch(JOIN) | 
The @Any annotation defines a polymorphic
        association to classes from multiple tables. This type of mapping
        always requires more than one column. The first column holds the type
        of the associated entity. The remaining columns hold the identifier.
        It is impossible to specify a foreign key constraint for this kind of
        association, so this is most certainly not meant as the usual way of
        mapping (polymorphic) associations. You should use this only in very
        special cases (eg. 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.
@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;
}
idType represents the target entities
        identifier property type and metaType the
        metadata type (usually String).
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;
}
It is possible to set
the batch size for collections using @BatchSize
the where clause, using @Where (applied on the target entity) or @WhereJoinTable (applied on the association table)
the check clause, using @Check
the SQL order by clause, using @OrderBy
the delete cascade strategy through @OnDelete(action=OnDeleteAction.CASCADE)
the collection immutability using @Immutable: if set specifies that the elements of the collection never change (a minor performance optimization in some cases)
a custom collection persister (ie the persistence strategy
              used) using @Persister: the class must
              implement
              org.hibernate.persister.collectionCollectionPersister
You can also declare a sort comparator. Use the
        @Sort annotation. Expressing the comparator type
        you want between unsorted, natural or custom comparator. If you want
        to use your own comparator implementation, you'll also have to express
        the implementation class using the comparator
        attribute. Note that you need to use either a
        SortedSet or a SortedMap
        interface.
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
@Sort(type = SortType.COMPARATOR, comparator = TicketComparator.class)
@Where(clause="1=1")
@OnDelete(action=OnDeleteAction.CASCADE)
public SortedSet<Ticket> getTickets() {
return tickets;
}
Please refer to the previous descriptions of these annotations for more informations.
Foreign key constraints, while generated by Hibernate, have a
        fairly unreadable name. You can override the constraint name by use
        @ForeignKey. Note that this annotation has to be
        placed on the owning side of the relationship,
        inverseName referencing to the other side
        constraint.
@Entity
public class Woman {
...
@ManyToMany(cascade = {CascadeType.ALL})
@ForeignKey(name = "TO_WOMAN_FK", inverseName = "TO_MAN_FK")
public Set<Man> getMens() {
return mens;
}
}
alter table Man_Woman add constraint TO_WOMAN_FK foreign key (woman_id) references Woman
alter table Man_Woman add constraint TO_MAN_FK foreign key (man_id) references Man
A bidirectional association where one end is an indexed
          collection (ie. represented as a @OrderColumn, or
          as a Map) requires special consideration. If a property on the
          associated class explicitly maps the indexed value, the use of
          mappedBy is permitted:
@Entity
public class Parent {
@OneToMany(mappedBy="parent")
@OrderColumn(name="order")
private List<Child> children;
...
}
@Entity
public class Child {
...
//the index column is mapped as a property in the associated entity
@Column(name="order")
private int order;
@ManyToOne
@JoinColumn(name="parent_id", nullable=false)
private Parent parent;
...
}
But, if there is no such property on the child class, we can't
          think of the association as truly bidirectional (there is
          information available at one end of the association that is not
          available at the other end: the index). In this case, we can't map
          the collection as mappedBy. Instead, we could use
          the following mapping:
@Entity
public class Parent {
@OneToMany
@OrderColumn(name="order")
@JoinColumn(name="parent_id", nullable=false)
private List<Child> children;
...
}
@Entity
public class Child {
...
@ManyToOne
@JoinColumn(name="parent_id", insertable=false, updatable=false, nullable=false)
private Parent parent;
...
}
Note that in this mapping, the collection-valued end of the association is responsible for updating the foreign key.
Another interesting feature is the ability to define a
          surrogate primary key to a bag collection. This remove pretty much
          all of the drawbacks of bags: update and removal are efficient, more
          than one EAGER bag per query or per entity. This
          primary key will be contained in a additional column of your
          collection table but will not be visible to the Java application.
          @CollectionId is used to mark a collection as id bag, it also allow
          to override the primary key column(s), the primary key type and the
          generator strategy. The strategy can be identity,
          or any defined generator name of your application.
@Entity
@TableGenerator(name="ids_generator", table="IDS")
public class Passport {
...
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="PASSPORT_VISASTAMP")
@CollectionId(
columns = @Column(name="COLLECTION_ID"),
type=@Type(type="long"),
generator = "ids_generator"
)
private Collection<Stamp> visaStamp = new ArrayList();
...
}
@ManyToAny allows polymorphic
          associations to classes from multiple tables. This type of mapping
          always requires more than one column. The first column holds the
          type of the associated entity. The remaining columns hold the
          identifier. It is impossible to specify a foreign key constraint for
          this kind of association, so this is most certainly not meant as the
          usual way of mapping (polymorphic) associations. You should use this
          only in very special cases (eg. audit logs, user session data,
          etc).
@ManyToAny(
metaColumn = @Column( name = "property_type" ) )
@AnyMetaDef(
idType = "integer",
metaType = "string",
metaValues = {
@MetaValue( value = "S", targetEntity = StringProperty.class ),
@MetaValue( value = "I", targetEntity = IntegerProperty.class ) } )
@Cascade( { org.hibernate.annotations.CascadeType.ALL } )
@JoinTable( name = "obj_properties", joinColumns = @JoinColumn( name = "obj_id" ),
inverseJoinColumns = @JoinColumn( name = "property_id" ) )
public List<Property> getGeneralProperties() {
Like @Any,
          @ManyToAny can use named
          @AnyDefs, see Section 2.4.5.2, “@Any” for more info.
Hibernate offers more operations than the Java Persistence
      specification. You can use the @Cascade annotation to
      cascade the following operations:
PERSIST
MERGE
REMOVE
REFRESH
DELETE
SAVE_UPDATE
REPLICATE
DELETE_ORPHAN (alternatively, use the
          @OneToOne.orphanRemoval or
          @OneToMany.orphanRemoval flag)
LOCK
EVICT (alternatively, use the standard DETACH flag).
This is especially useful for SAVE_UPDATE
      (which is the operation cascaded at flush time if you use plain
      Hibernate Annotations - Hibernate EntityManager cascade
      PERSIST at flush time as per the
      specification).
@OneToMany( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
@Cascade(org.hibernate.annotations.CascadeType.REPLICATE)
public Collection<Employer> getEmployers()
It is recommended to use @Cascade to
      compliment @*To*(cascade=...) as shown in the
      previous example.
Hibernate has the ability to apply arbitrary filters on top of your data. Those filters are applied at runtime on a given session. First, you need to define them.
@org.hibernate.annotations.FilterDef or
      @FilterDefs define filter definition(s) used by
      filter(s) using the same name. A filter definition has a name() and an
      array of parameters(). A parameter will allow you to adjust the behavior
      of the filter at runtime. Each parameter is defined by a
      @ParamDef which has a name and a type. You can also
      define a defaultCondition() parameter for a given
      @FilterDef to set the default condition to use when
      none are defined in each individual @Filter. A
      @FilterDef(s) can be defined at the class or package
      level.
We now need to define the SQL filter clause applied to either the
      entity load or the collection load. @Filter is used
      and placed either on the entity or the collection element
@Entity
@FilterDef(name="minLength", parameters=@ParamDef( name="minLength", type="integer" ) )
@Filters( {
@Filter(name="betweenLength", condition=":minLength <= length and :maxLength >= length"),
@Filter(name="minLength", condition=":minLength <= length")
} )
public class Forest { ... }
When the collection use an association table as a relational
      representation, you might want to apply the filter condition to the
      association table itself or to the target entity table. To apply the
      constraint on the target entity, use the regular
      @Filter annotation. However, if you wan to target the
      association table, use the @FilterJoinTable
      annotation.
@OneToMany
@JoinTable
//filter on the target entity table
@Filter(name="betweenLength", condition=":minLength <= length and :maxLength >= length")
//filter on the association table
@FilterJoinTable(name="security", condition=":userlevel >= requredLevel")
public Set<Forest> getForests() { ... }
Since Hibernate has more features on named queries than the one
      defined in the JPA specification,
      @org.hibernate.annotations.NamedQuery,
      @org.hibernate.annotations.NamedQueries,
      @org.hibernate.annotations.NamedNativeQuery and
      @org.hibernate.annotations.NamedNativeQueries have
      been introduced. They add some attributes to the standard version and
      can be used as a replacement:
flushMode: define the query flush mode (Always, Auto, Commit or Manual)
cacheable: whether the query should be cached or not
cacheRegion: cache region used if the query is cached
fetchSize: JDBC statement fetch size for this query
timeout: query time out
callable: for native queries only, to be set to true for stored procedures
comment: if comments are activated, the comment seen when the query is sent to the database.
cacheMode: Cache interaction mode (get, ignore, normal, put or refresh)
readOnly: whether or not the elements retrievent from the query are in read only mode.
Those hints can be set in a standard
      @javax.persistence.NamedQuery annotations through the
      detyped @QueryHint. Another key advantage is the
      ability to set those annotations at a package level.
Hibernate gives you the ability to override every single SQL statement generated. We have seen native SQL query usage already, but you can also override the SQL statement used to load or change the state of entities.
@Entity
@Table(name="CHAOS")
@SQLInsert( sql="INSERT INTO CHAOS(size, name, nickname, id) VALUES(?,upper(?),?,?)")
@SQLUpdate( sql="UPDATE CHAOS SET size = ?, name = upper(?), nickname = ? WHERE id = ?")
@SQLDelete( sql="DELETE CHAOS WHERE id = ?")
@SQLDeleteAll( sql="DELETE CHAOS")
@Loader(namedQuery = "chaos")
@NamedNativeQuery(name="chaos", query="select id, size, name, lower( nickname ) as nickname from CHAOS where id= ?", resultClass = Chaos.class)
public class Chaos {
@Id
private Long id;
private Long size;
private String name;
private String nickname;
@SQLInsert, @SQLUpdate,
      @SQLDelete, @SQLDeleteAll
      respectively override the INSERT statement, UPDATE statement, DELETE
      statement, DELETE statement to remove all entities.
If you expect to call a store procedure, be sure to set the
      callable attribute to true
      (@SQLInsert(callable=true, ...)).
To check that the execution happens correctly, Hibernate allows you to define one of those three strategies:
NONE: no check is performed: the store procedure is expected to fail upon issues
COUNT: use of rowcount to check that the update is successful
PARAM: like COUNT but using an output parameter rather that the standard mechanism
To define the result check style, use the check
      parameter (@SQLUpdate(check=ResultCheckStyle.COUNT,
      ...)).
You can also override the SQL load statement by a native SQL query
      or a HQL query. You just have to refer to a named query with the
       annotation.@Loader
You can use the exact same set of annotations to override the collection related statements.
@OneToMany
@JoinColumn(name="chaos_fk")
@SQLInsert( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = ? where id = ?")
@SQLDelete( sql="UPDATE CASIMIR_PARTICULE SET chaos_fk = null where id = ?")
private Set<CasimirParticle> particles = new HashSet<CasimirParticle>();
The parameters order is important and is defined by the order
      Hibernate handle properties. You can see the expected order by enabling
      debug logging for the org.hibernate.persister.entity
      level. With this level enabled Hibernate will print out the static SQL
      that is used to create, update, delete etc. entities. (To see the
      expected sequence, remember to not include your custom SQL through
      annotations as that will override the Hibernate generated static
      sql.)
Overriding SQL statements for secondary tables is also possible
      using @org.hibernate.annotations.Table and either (or
      all) attributes sqlInsert,
      sqlUpdate, sqlDelete:
@Entity
@SecondaryTables({
@SecondaryTable(name = "`Cat nbr1`"),
@SecondaryTable(name = "Cat2"})
@org.hibernate.annotations.Tables( {
@Table(appliesTo = "Cat", comment = "My cat table" ),
@Table(appliesTo = "Cat2", foreignKey = @ForeignKey(name="FK_CAT2_CAT"), fetch = FetchMode.SELECT,
sqlInsert=@SQLInsert(sql="insert into Cat2(storyPart2, id) values(upper(?), ?)") )
} )
public class Cat implements Serializable {
The previous example also show that you can give a comment to a given table (promary or secondary): This comment will be used for DDL generation.
org.hibernate.tuple.Tuplizer, and its
      sub-interfaces, are responsible for managing a particular representation
      of a piece of data, given that representation's
      org.hibernate.EntityMode. If a given piece of data is
      thought of as a data structure, then a tuplizer is the thing which knows
      how to create such a data structure and how to extract values from and
      inject values into such a data structure. For example, for the POJO
      entity mode, the correpsonding tuplizer knows how create the POJO
      through its constructor and how to access the POJO properties using the
      defined property accessors. There are two high-level types of Tuplizers,
      represented by the
      org.hibernate.tuple.EntityTuplizer and
      org.hibernate.tuple.ComponentTuplizer interfaces.
      EntityTuplizers are responsible for managing the above mentioned
      contracts in regards to entities, while
      ComponentTuplizers do the same for components.
      Check the Hibernate reference documentation for more information.
To define tuplixer in annotations, simply use the
      @Tuplizer annotation on the according element
@Entity
@Tuplizer(impl = DynamicEntityTuplizer.class)
public interface Cuisine {
@Id
@GeneratedValue
public Long getId();
public void setId(Long id);
public String getName();
public void setName(String name);
@Tuplizer(impl = DynamicComponentTuplizer.class)
public Country getCountry();
public void setCountry(Country country);
}
In Section 2.4.5.1, “Lazy options and
        fetching modes” we have
      seen how to affect the fetching strategy for associated objects using
      the @Fetch annotation. An alternative approach is
      a so called fetch profile. A fetch profile is a named configuration
      associated with the org.hibernate.SessionFactory
      which gets enabled on the org.hibernate.Session.
      Once enabled on a org.hibernate.Session, the
      fetch profile will be in affect for that session until it is explicitly
      disabled. Lets look at an example:
@Entity
@FetchProfile(name = "customer-with-orders", fetchOverrides = {
@FetchProfile.FetchOverride(entity = Customer.class, association = "orders", mode = FetchMode.JOIN)
})
public class Customer {
@Id
@GeneratedValue
private long id;
private String name;
private long customerNumber;
@OneToMany
private Set<Order> orders;
// standard getter/setter
...
}
In the normal case the orders association would be lazy loaded by Hibernate, but in a usecase where it is more efficient to load the customer and their orders together you could do something like this:
Session session = ...;
session.enableFetchProfile( "customer-with-orders" ); // name matches @FetchProfile name
Customer customer = (Customer) session.get( Customer.class, customerId );
session.disableFetchProfile( "customer-with-orders" ); // or just close the session
...
Fetch profile definitions are global and it does not matter on
        which class you place them. You can place the
        @FetchProfile annotation either onto a class or
        package (package-info.java). In order to define multiple fetch
        profiles for the same class or package
        @FetchProfiles can be used.
Currently only join style fetch profiles are supported, but they plan is to support additional styles. See HHH-3414 for details. Refer also to the discussion about fetch profiles in the Hibernate Core documentation.
The primary target for metadata in EJB3 is annotations, but the EJB3 specification provides a way to override or replace the annotation defined metadata through an XML deployment descriptor. In the current release only pure EJB3 annotations overriding are supported. If you wish to use Hibernate specific features in some entities, you'll have to either use annotations or fallback to hbm files. You can of course mix and match annotated entities and entities describes in hbm files.
The unit test suite shows some additional XML file samples.
The XML deployment descriptor structure has been designed to reflect the annotations one. So if you know the annotations structure, using the XML schema will be straightforward for you.
You can define one or more XML files describing your metadata, these files will be merged by the overriding engine.
You can define global level metadata available for all XML files. You must not define these metadata more than once per deployment.
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
version="2.0">
<persistence-unit-metadata>
<xml-mapping-metadata-complete/>
<persistence-unit-defaults>
<schema>myschema</schema>
<catalog>mycatalog</catalog>
<cascade-persist/>
</persistence-unit-defaults>
</persistence-unit-metadata>
xml-mapping-metadata-complete means that all
      entity, mapped-superclasses and embeddable metadata should be picked up
      from XML (ie ignore annotations).
schema / catalog will override all default
      definitions of schema and catalog in the metadata (both XML and
      annotations).
cascade-persist means that all associations
      have PERSIST as a cascade type. We recommend you to not use this
      feature.
You can either define or override metadata informations on a given entity.
<?xml version="1.0" encoding="UTF-8"?> <entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd" version="2.0"> <package>o
rg.hibernate.test.annotations.reflection</package> <entity cl
ass="Administration" access="PROPERTY" metadata-complete="true"> <table
name="tbl_admin"> <unique-constraint> <column-name>firstname</column-name> <column-name>lastname</column-name> </unique-constraint> </table> <secon
dary-table name="admin2"> <primary-key-join-column name="admin_id" referenced-column-name="id"/> <unique-constraint> <column-name>address</column-name> </unique-constraint> </secondary-table> <id-cl
ass class="SocialSecurityNumber"/> <inher
itance strategy="JOINED"/> <seque
nce-generator name="seqhilo" sequence-name="seqhilo"/> <table
-generator name="table" table="tablehilo"/> ... </entity> <entity class="PostalAdministration"> <prima
ry-key-join-column name="id"/> ... </entity> </entity-mappings>
  | 
  | 
  | 
  | 
  | 
 
 An entity has to have a  You can overrides entity name through the
             For metadata complete (see below) element, you can define an
              | 
  | 
 You can define one or several unique constraints as seen in the example  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings 
  xmlns="http://java.sun.com/xml/ns/persistence/orm"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_2_0.xsd"
  version="2.0">
    <package>org.hibernate.test.annotations.reflection</package>
    <entity class="Music" access="PROPERTY" metadata-complete="true">
        <discr
iminator-value>Generic</discriminator-value>
        <discriminator-column length="34"/>
        ...
    </entity>
    <entity class="PostalAdministration">
        <primary-key-join-column name="id"/>
        <named
-query name="adminById">
            <query>select m from Administration m where m.id = :id</query>
            <hint name="org.hibernate.timeout" value="200"/>
        </named-query>
        <named
-native-query name="allAdmin" result-set-mapping="adminrs">
            <query>select *, count(taxpayer_id) as taxPayerNumber 
            from Administration, TaxPayer
            where taxpayer_admin_id = admin_id group by ...</query>
            <hint name="org.hibernate.timeout" value="200"/>
        </named-native-query>
        <sql-r
esult-set-mapping name="adminrs">
            <entity-result entity-class="Administration">
                <field-result name="name" column="fld_name"/>
            </entity-result>
            <column-result name="taxPayerNumber"/>
        </sql-result-set-mapping>
        <attri
bute-override name="ground">
            <column name="fld_ground" unique="true" scale="2"/>
        </attribute-override>
        <association-override name="referer">
            <join-column name="referer_id" referenced-column-name="id"/>
        </association-override>
        ...
    </entity>
</entity-mappings>
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
  | 
Same applies for <embeddable> and
      <mapped-superclass>.
You can of course defines XML overriding for properties. If
      metadata complete is defined, then additional properties (ie at the Java
      level) will be ignored. Otherwise, once you start overriding a property,
      all annotations on the given property are ignored. All property level
      metadata behave in entity/attributes,
      mapped-superclass/attributes or
      embeddable/attributes.
<attributes>
<id name="id">
<column name="fld_id"/>
<generated-value generator="generator" strategy="SEQUENCE"/>
<temporal>DATE</temporal>
<sequence-generator name="generator" sequence-name="seq"/>
</id>
<version name="version"/>
<embedded name="embeddedObject">
<attribute-override name"subproperty">
<column name="my_column"/>
</attribute-override>
</embedded>
<basic name="status" optional="false">
<enumerated>STRING</enumerated>
</basic>
<basic name="serial" optional="true">
<column name="serialbytes"/>
<lob/>
</basic>
<basic name="terminusTime" fetch="LAZY">
<temporal>TIMESTAMP</temporal>
</basic>
</attributes>
You can override a property through id,
      embedded-id, version,
      embedded and basic. Each of these
      elements can have subelements accordingly: lob,
      temporal, enumerated,
      column.
You can define XML overriding for associations. All association
      level metadata behave in entity/attributes,
      mapped-superclass/attributes or
      embeddable/attributes.
<attributes>
<one-to-many name="players" fetch="EAGER">
<map-key name="name"/>
<join-column name="driver"/>
<join-column name="number"/>
</one-to-many>
<many-to-many name="roads" target-entity="Administration">
<order-by>maxSpeed</order-by>
<join-table name="bus_road">
<join-column name="driver"/>
<join-column name="number"/>
<inverse-join-column name="road_id"/>
<unique-constraint>
<column-name>driver</column-name>
<column-name>number</column-name>
</unique-constraint>
</join-table>
</many-to-many>
<many-to-many name="allTimeDrivers" mapped-by="drivenBuses">
</attributes>
You can override an association through
      one-to-many, one-to-one,
      many-to-one, and many-to-many.
      Each of these elements can have subelements accordingly:
      join-table (which can have
      join-columns and
      inverse-join-columns),
      ,
      join-columnsmap-key, and order-by.
      mapped-by and target-entity can be
      defined as attributes when it makes sense. Once again the structure is
      reflects the annotations structure. You can find all semantic
      informations in the chapter describing annotations.
Hibernate Annotations mainly focuses on persistence metadata. The project also have a nice integration with some external modules.
Bean Validation standardizes how to define and declare domain model level constraints. You can, for example, express that a property should never be null, that the account balance should be strictly positive, etc. These domain model constraints are declared in the bean itself by annotating its properties. Bean Validation can then read them and check for constraint violations. The validation mechanism can be executed in different layers in your application without having to duplicate any of these rules (presentation layer, data access layer). Following the DRY principle, Bean Validation and its reference implementation Hibernate Validator has been designed for that purpose.
The integration between Hibernate and Bean Validation works at two levels. First, it is able to check in-memory instances of a class for constraint violations. Second, it can apply the constraints to the Hibernate metamodel and incorporate them into the generated database schema.
Each constraint annotation is associated to a validator implementation responsible for checking the constraint on the entity instance. A validator can also (optionally) apply the constraint to the Hibernate metamodel, allowing Hibernate to generate DDL that expresses the constraint. With the appropriate event listener, you can execute the checking operation on inserts, updates and deletes done by Hibernate.
When checking instances at runtime, Hibernate Validator returns
    information about constraint violations in a set of
    ConstraintViolations. Among other information, the
    ConstraintViolation contains an error description
    message that can embed the parameter values bundle with the annotation
    (eg. size limit), and message strings that may be externalized to a
    ResourceBundle.
To enable the Hibernate - Bean Validation integration, simply add a Bean Validation provider (preferably Hibernate Validation 4) in your classpath.
By default, no configuration is necessary.
The Default group is validated on entity
      insert and update and the database model is updated accordingly based on
      the Default group as well.
You can customize the Bean Validation integration by setting the
      validation mode. Use the
      javax.persistence.validation.mode property and set it
      up for example in your persistence.xml file or your
      hibernate.cfg.xml file. Several options are
      possible:
auto (default): enable integration between
          Bean Validation and Hibernate (callback and ddl generation) only if
          Bean Validation is present in the classpath.
none: disable all integration between Bean
          Validation and Hibernate
callback: only validate entities when they
          are either inserted, updated or deleted. An exception is raised if
          no Bean Validation provider is present in the classpath.
ddl: only apply constraints to the database
          schema when generated by Hibernate. An exception is raised if no
          Bean Validation provider is present in the classpath. This value is
          not defined by the Java Persistence spec and is specific to
          Hibernate.
You can use both callback and
        ddl together by setting the property to
        callback, dll
<persistence ...>
<persistence-unit ...>
...
<properties>
<property name="javax.persistence.validation.mode"
value="callback, ddl"/>
</properties>
</persistence-unit>
</persistence>
This is equivalent to auto except that if no
        Bean Validation provider is present, an exception is raised.
If you want to validate different groups during insertion, update and deletion, use:
javax.persistence.validation.group.pre-persist:
          groups validated when an entity is about to be persisted (default to
          Default)
javax.persistence.validation.group.pre-update:
          groups validated when an entity is about to be updated (default to
          Default)
javax.persistence.validation.group.pre-remove:
          groups validated when an entity is about to be deleted (default to
          no group)
org.hibernate.validator.group.ddl: groups
          considered when applying constraints on the database schema (default
          to Default)
Each property accepts the fully qualified class names of the groups validated separated by a comma (,)
Example 4.1. Using custom groups for validation
<persistence ...>
<persistence-unit ...>
...
<properties>
<property name="javax.persistence.validation.group.pre-update"
value="javax.validation.group.Default, com.acme.group.Strict"/>
<property name="javax.persistence.validation.group.pre-remove"
value="com.acme.group.OnDelete"/>
<property name="org.hibernate.validator.group.ddl"
value="com.acme.group.DDL"/>
</properties>
</persistence-unit>
</persistence>
You can set these properties in
        hibernate.cfg.xml,
        hibernate.properties or programmatically.
If an entity is found to be invalid, the list of constraint
      violations is propagated by the
      ConstraintViolationException which exposes the
      set of ConstraintViolations.
This exception is wrapped in a
      RollbackException when the violation happens at
      commit time. Otherwise the
      ConstraintViolationException is returned (for
      example when calling flush(). Note that
      generally, catchable violations are validated at a higher level (for
      example in Seam / JSF 2 via the JSF - Bean Validation integration or in
      your business layer by explicitly calling Bean Validation).
An application code will rarely be looking for a
      ConstraintViolationException raised by Hibernate.
      This exception should be treated as fatal and the persistence context
      should be discarded (EntityManager or
      Session).
Hibernate uses Bean Validation constraints to generate an accurate database schema:
@NotNull leads to a not null column
          (unless it conflicts with components or table inheritance)
@Size.max leads to a
          varchar(max) definition for Strings
@Min, @Max lead
          to column checks (like value <= max)
@Digits leads to the definition of
          precision and scale (ever wondered which is which? It's easy now
          with @Digits :) )
These constraints can be declared directly on the entity properties or indirectly by using constraint composition.
We strongly encourage you to use Hibernate Validator 4 and the Bean Validation integration. Consider Hibernate Validator 3 as legacy.
Annotations are a very convenient and elegant way to specify invariant constraints for a domain model. You can, for example, express that a property should never be null, that the account balance should be strictly positive, etc. These domain model constraints are declared in the bean itself by annotating its properties. A validator can then read them and check for constraint violations. The validation mechanism can be executed in different layers in your application without having to duplicate any of these rules (presentation layer, data access layer). Following the DRY principle, Hibernate Validator has been designed for that purpose.
Hibernate Validator works at two levels. First, it is able to check in-memory instances of a class for constraint violations. Second, it can apply the constraints to the Hibernate metamodel and incorporate them into the generated database schema.
Each constraint annotation is associated to a validator implementation responsible for checking the constraint on the entity instance. A validator can also (optionally) apply the constraint to the Hibernate metamodel, allowing Hibernate to generate DDL that expresses the constraint. With the appropriate event listener, you can execute the checking operation on inserts and updates done by Hibernate. Hibernate Validator is not limited to use with Hibernate. You can easily use it anywhere in your application.
When checking instances at runtime, Hibernate Validator returns
      information about constraint violations in an array of
      InvalidValue s. Among other information, the
      InvalidValue contains an error description
      message that can embed the parameter values bundle with the annotation
      (eg. length limit), and message strings that may be externalized to a
      ResourceBundle .
If Hibernate Validator
      (hibernate-validator.jar) is available in the
      classpath, Hibernate Annotations will integrate in two ways:
Constraints will be applied to the Data Definition Language. In other words, the database schema will reflect the constraints (provided that you use the hbm2ddl tool).
Before an entity change is applied to the database (insert or
          update), the entity is validated. Validation errors, if any, will be
          carried over through an
          InvalidStateException.
For entities free of validation rules, the runtime performance cost is null.
To disable constraint propagation to DDL, set up
      hibernate.validator.apply_to_ddl to false in the
      configuration file. Such a need is very uncommon and not
      recommended.
To disable pre-entity change validation, set up
      hibernate.validator.autoregister_listeners to false
      in the configuration file. Such a need is very uncommon and not
      recommended.
Check the Hibernate Validator reference documentation for more information.
Full text search engines like Apache Lucene™ are a very powerful technology to bring free text/efficient queries to applications. If suffers several mismatches when dealing with a object domain model (keeping the index up to date, mismatch between the index structure and the domain model, querying mismatch...) Hibernate Search indexes your domain model thanks to a few annotations, takes care of the database / index synchronization and brings you back regular managed objects from free text queries. Hibernate Search is using Apache Lucene under the cover.
Hibernate Search integrates with Hibernate Annotations
      transparently provided that hibernate-search.jar is present in the
      classpath. If you do not wish to automatically register Hibernate Search
      event listeners, you can set
      hibernate.search.autoregister_listeners to false.
      Such a need is very uncommon and not recommended.
Check the Hibernate Search reference documentation for more information.
Copyright © 2004 Red Hat Inc. and the various authors