ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
# 8.4\. 组件作为联合标识符(Components as composite identifiers) 你可以使用一个组件作为一个实体类的标识符。 你的组件类必须满足以下要求: * 它必须实现`java.io.Serializable`接口 * 它必须重新实现`equals()`和`hashCode()`方法, 始终和组合关键字在数据库中的概念保持一致 _注意:在Hibernate3中,第二个要求并非是Hibernate强制必须的。但最好这样做。_ 你不能使用一个`IdentifierGenerator`产生组合关键字。一个应用程序必须分配它自己的标识符。 使用`&lt;composite-id&gt;` 标签(并且内嵌`&lt;key-property&gt;`元素)代替通常的`&lt;id&gt;`标签。比如,`OrderLine`类具有一个主键,这个主键依赖于`Order`的(联合)主键。 ``` <class name="OrderLine"> <composite-id name="id" class="OrderLineId"> <key-property name="lineId"/> <key-property name="orderId"/> <key-property name="customerId"/> </composite-id> <property name="name"/> <many-to-one name="order" class="Order" insert="false" update="false"> <column name="orderId"/> <column name="customerId"/> </many-to-one> .... </class> ``` 现在,任何指向`OrderLine`的外键都是复合的。在你的映射文件中,必须为其他类也这样声明。例如,一个指向`OrderLine`的关联可能被这样映射: ``` <many-to-one name="orderLine" class="OrderLine"> <!-- the "class" attribute is optional, as usual --> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/> </many-to-one> ``` (注意在各个地方`&lt;column&gt;`标签都是`column`属性的替代写法。) 指向`OrderLine`的`多对多`关联也使用联合外键: ``` <set name="undeliveredOrderLines"> <key column name="warehouseId"/> <many-to-many class="OrderLine"> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/> </many-to-many> </set> ``` 在`Order`中,`OrderLine`的集合则是这样: ``` <set name="orderLines" inverse="true"> <key> <column name="orderId"/> <column name="customerId"/> </key> <one-to-many class="OrderLine"/> </set> ``` (与通常一样,`&lt;one-to-many&gt;`元素不声明任何列.) 假若`OrderLine`本身拥有一个集合,它也具有组合外键。 ``` <class name="OrderLine"> .... .... <list name="deliveryAttempts"> <key> <!-- a collection inherits the composite key type --> <column name="lineId"/> <column name="orderId"/> <column name="customerId"/> </key> <list-index column="attemptId" base="1"/> <composite-element class="DeliveryAttempt"> ... </composite-element> </set> </class> ```