составной ключ гибернации - PullRequest
8 голосов
/ 20 февраля 2010

Необходимо ли, чтобы составной идентификатор был сопоставлен с классом ??

это может быть так?

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

или должно быть

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

Если это необходимо, если у нас есть составной ключ, тогда этот класс должен реализовать метод equals() и override()?

Ответы [ 3 ]

26 голосов
/ 20 февраля 2010

Hibernate должен уметь сравнивать и сериализовать идентификаторы. Таким образом, класс идентификатора должен быть сериализуемым и переопределять hashCode () и equals () в соответствии с представлением базы данных о равенстве составного ключа.

Если у вас есть составной идентификатор, сопоставленный как свойства объекта, сам объект является идентификатором.

Второй подход называется сопоставленным составным идентификатором, в котором свойства идентификатора, названные внутри элемента <составной-идентификатор>, дублируются как для постоянного класса, так и для отдельного класса идентификаторов

Наконец, составной идентификатор может быть классом компонента. В этом случае класс компонента является идентификатором класса.

Обратите внимание, что настоятельно рекомендуется иметь идентификатор в отдельном классе. В противном случае у вас будут только очень неуклюжие способы поиска вашего объекта с использованием session.get () или session.load ().

Соответствующие разделы справочной документации:

В этом примере составной идентификатор отображается как свойства объекта. (Ниже предполагается, что вы определяете класс Employee).

<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()
}

Составной составной идентификатор:

<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()
}

Компонент в качестве составного идентификатора:

<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()
}
4 голосов
/ 28 февраля 2010

Оба возможны. Если вы используете

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

Тогда для представления ключа не требуется отдельный класс. Значения идентификатора берутся из свойств самого объекта.

Если вы используете

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

Тогда указанный класс будет использоваться как держатель для ключевых свойств. Однако класс сущности должен также иметь эти свойства - значения хранятся как в классе сущности, так и в классе составного идентификатора. Класс сущности не знает о классе ключа. Не очень приятно, на мой взгляд.

Существует более приятный третий подход, описанный в документации здесь :

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

Здесь составной ключ представлен классом OrderLineId, экземпляр которого хранится в поле id в классе сущности. Это значительно упрощает разделение между сущностью и ключом.

2 голосов
/ 21 февраля 2012

Если у вас есть составной ключ, который содержит отношения с другими объектами, сделайте это следующим образом:

<composite-id>
    <key-many-to-one name="employee" column="FK_EMPLOYEE" entity-name="net.package.name.Employee" />
    <key-many-to-one name="department" column="FK_DEPARTMENT" entity-name="net.package.name.Department" />
</composite-id>
...