<composite-id
name="propertyName"
class="ClassName"
mapped="true|false"
access="field|property|ClassName">
node="element-name|."
<key-property name="propertyName" type="typename" column="column_name"/>
<key-many-to-one name="propertyName class="ClassName" column="column_name"/>
......
</composite-id>
For a table with a composite key, you may map multiple properties of the class as identifier properties. The <composite-id> element accepts <key-property> property mappings and <key-many-to-one> mappings as child elements.
<composite-id>
<key-property name="medicareNumber"/>
<key-property name="dependent"/>
</composite-id>
Your persistent class must override equals() and hashCode() to implement composite identifier equality. It must also implements Serializable.
Unfortunately, this approach to composite identifiers means that a persistent object is its own identifier. There is no convenient "handle" other than the object itself. You must instantiate an instance of the persistent class itself and populate its identifier properties before you can load() the persistent state associated with a composite key. We call this approach an embedded composite identifier, and discourage it for serious applications.
A second approach is what we call a mapped composite identifier, where the identifier properties named inside the <composite-id> element are duplicated on both the persistent class and a separate identifier class.
<composite-id class="MedicareId" mapped="true">
<key-property name="medicareNumber"/>
<key-property name="dependent"/>
</composite-id>
In this example, both the composite identifier class, MedicareId, and the entity class itself have properties named medicareNumber and dependent. The identifier class must override equals() and hashCode() and implement. Serializable. The disadvantage of this approach is quite obvious - code duplication.
The following attributes are used to specify a mapped composite identifier:
mapped (optional, defaults to false): indicates that a mapped composite identifier is used, and that the contained property mappings refer to both the entity class and the composite identifier class.
class (optional, but required for a mapped composite identifier): The class used as a composite identifier.
We will describe a third, even more convenient approach where the composite identifier is implemented as a component class in Section 8.4, “Components as composite identifiers”. The attributes described below apply only to this alternative approach:
name (optional, required for this approach): A property of component type that holds the composite identifier (see chapter 9).
access (optional - defaults to property): The strategy Hibernate should use for accessing the property value.
class (optional - defaults to the property type determined by reflection): The component class used as a composite identifier (see next section).
This third approach, an identifier component is the one we recommend for almost all applications.