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 がある場合、エンティティ自体が識別子になります。

2 番目のアプローチは、マップされた複合識別子と呼ばれ、 <composite-id> 要素内で名前が付けられた識別子プロパティが、永続クラスと別の識別子クラスの両方で複製されます。

最後に、composite-id はコンポーネント クラスの場合があります。この場合、コンポーネント クラスは識別子クラスです。

ID を別のクラスにすることを強くお勧めします。そうしないと、session.get() または session.load() を使用してオブジェクトを検索する非常に扱いにくい方法しかありません。

リファレンス ドキュメントの関連セクション:

この例では、composite-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 クラスの両方に格納されます。エンティティ クラスには、キー クラスに関する知識がありません。私の意見では、あまり良くありません。

ここのドキュメントで説明されている、より優れた3番目のアプローチがあります。

<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 に答える