Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hibernate composite key

Is it necessary that composite-id should be mapped to class ??

can it be like this ?

<composite-id>
  <key-property=..../>
  <key-property=..../>
</composite-id>

or should be

<composite-id class=....>
  <key-property=..../>
  <key-property=..../>
</composite-id>

should that necessary that if we have composite key then that class should implement equals() and override() method ?

like image 576
Senthilnathan Avatar asked Feb 20 '10 06:02

Senthilnathan


People also ask

What is the composite key in Hibernate?

A composite primary key, also called a composite key, is a combination of two or more columns to form a primary key for a table. In JPA, we have two options to define the composite keys: the @IdClass and @EmbeddedId annotations.

Can we use composite keys in Hibernate?

Use embeddable objects to join two primary keys into one composite key. Every JPA entity has a primary key, but some entities have more than one value as their primary key. In this case, you need to use a composite key. This Java tip introduces you to using composite keys in JPA and Hibernate.


2 Answers

Hibernate needs to be able to compare and serialize identifiers. So the identifier class must be serializable, and override hashCode() and equals() consistently with the database's notion of composite key equality.

If you have a composite id mapped as properties of the entity, the entity itself is the identifier.

A second approach is called 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

Finally, a composite-id may be a component class. In this case the component class is the identifier class.

Note that it is strongly recommended to have the ID a separate class. Otherwise you will have only very awkward ways to lookup your object using session.get() or session.load().

Relevant sections of the Reference Documentation:

  • composite-id
  • Components as composite identifiers

In this example, a composite-id is mapped as properties of the entity. (The following assume you are defining the Employee class).

<composite-id>
    <key-property name="EmployeeNumber"/>
    <key-property name="Dependent"/>
</composite-id>

class EmployeeAssignment implements Serializable
{
    string getEmployeeNumber()
    void setEmployeeNumber( string value )
    string getDepartment()
    void setDepartment( string value )
    boolean equals( Object obj )
    int hashCode()
}

A mapped composite-id:

<composite-id class="EmployeeAssignmentId" mapped="true">
    <key-property name="EmployeeNumber"/>
    <key-property name="Dependent"/>
</composite-id>

class EmployeeAssignment
{
    string getEmployeeNumber()
    void setEmployeeNumber( string value )
    string getDepartment()
    void setDepartment( string value )
}

class EmployeeAssignmentId implements Serializable
{
    string getEmployeeNumber()
    void setEmployeeNumber( string value )
    string getDepartment()
    void setDepartment( string value )
    boolean equals( Object obj )
    int hashCode()
}

A component as a composite-id:

<composite-id name="Id" class="EmployeeAssignmentId">
    <key-property name="EmployeeNumber"/>
    <key-property name="Dependent"/>
</composite-id>

class EmployeeAssignment
{
    EmployeeAssignmentId getId()
    void setId( EmployeeAssignmentId value )
}

class EmployeeAssignmentId implements Serializable
{
    string getEmployeeNumber()
    void setEmployeeNumber( string value )
    string getDepartment()
    void setDepartment( string value )
    boolean equals( Object obj )
    int hashCode()
}
like image 103
Lachlan Roche Avatar answered Sep 23 '22 01:09

Lachlan Roche


Both are possible. If you use

<composite-id>
  <key-property=..../>
  <key-property=..../>
</composite-id>

Then no separate class is required to represent the key. The ID values are taken from the properties of the entity itself.

If you use

<composite-id class="....">
  <key-property=..../>
  <key-property=..../>
</composite-id>

Then the specified class will be a used as a holder for the key properties. However, the entity class must also have these properties - the values are stored both in the entity class and the composite ID class. The entity class has no knowledge of the key class. Not very nice, in my opinion.

There is a nicer 3rd approach, described in the docs here:

<composite-id name="id" class="OrderLineId">
    <key-property name="lineId"/>
    <key-property name="orderId"/>
    <key-property name="customerId"/>
</composite-id>

Here, the composite key is represented by the class OrderLineId, an instance of which is stored under the field id in the entity class. This keeps the separation between entity and key much cleaner.

like image 33
skaffman Avatar answered Sep 22 '22 01:09

skaffman