8

是否有必要将复合ID映射到类?

可以这样吗?

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

或者应该是

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

如果我们有复合键,那么该类应该实现equals()override()方法是否有必要?

4

3 回答 3

26

Hibernate 需要能够比较和序列化标识符。所以标识符类必须是可序列化的,并且覆盖 hashCode() 和 equals() 与数据库的复合键相等概念一致。

如果您将复合 id 映射为实体的属性,则实体本身就是标识符。

第二种方法称为映射复合标识符,其中在 <composite-id> 元素内命名的标识符属性在持久类和单独的标识符类上都重复

最后,composite-id 可能是一个组件类。在这种情况下,组件类是标识符类。

请注意,强烈建议将 ID 设置为单独的类。否则,您将只有非常尴尬的方式来使用 session.get() 或 session.load() 来查找您的对象。

参考文档的相关部分:

在此示例中,复合 ID 被映射为实体的属性。(以下假设您正在定义 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()
}

映射的复合 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()
}

作为复合 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()
}
于 2010-02-20T06:34:51.963 回答
4

两者都是可能的。如果你使用

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

然后不需要单独的类来表示密钥。ID 值取自实体本身的属性。

如果你使用

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

然后指定的类将用作关键属性的持有者。但是,实体类必须具有这些属性 - 值存储在实体类和复合 ID 类中。实体类不知道键类。在我看来,不是很好。

有一种更好的第三种方法,在此处的文档中进行了描述:

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

在这里,复合键由 class 表示OrderLineId,其实例存储在id实体类的字段下。这使实体和密钥之间的分离更加清晰。

于 2010-02-28T16:19:52.347 回答
2

如果您有一个包含与其他实体的关系的复合键,请这样做:

<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>
于 2012-02-21T11:38:17.293 回答