Действительно ли необходимо, чтобы составной идентификатор был отображен на классе??
это может быть похожим на это?
<composite-id>
<key-property=..../>
<key-property=..../>
</composite-id>
или должен быть
<composite-id class=....>
<key-property=..../>
<key-property=..../>
</composite-id>
если это необходимое, что, если у нас есть составной ключ затем, что класс должен реализовать equals()
и override()
метод?
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()
}
Оба варианта возможны. Если вы используете
<composite-id>
<key-property=..../>
<key-property=..../>
</composite-id>
, то отдельный класс для представления ключа не требуется. Значения 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
в классе сущности. Это делает разделение между сущностью и ключом намного более чистым.