是否有必要将composite-id映射到类??
可以这样吗?
<composite-id>
<key-property=..../>
<key-property=..../>
</composite-id>
或应该是
<composite-id class=....>
<key-property=..../>
<key-property=..../>
</composite-id>
是否必要,如果我们有复合键,那么该类应该实现equals()
和override()
方法?
答案 0 :(得分:26)
Hibernate需要能够比较和序列化标识符。因此标识符类必须是可序列化的,并且与数据库的复合键相等概念一致地覆盖hashCode()和equals()。
如果您将复合ID映射为实体的属性,则实体本身就是标识符。
第二种方法称为映射复合标识符,其中在&lt; composite-id&gt;内部命名的标识符属性。元素在持久化类和单独的标识符类
上都是重复的最后,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()
}
映射的composite-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()
}
作为composite-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()
}
答案 1 :(得分:4)
两者都有可能。如果你使用
<composite-id>
<key-property=..../>
<key-property=..../>
</composite-id>
然后,不需要单独的类来表示密钥。 ID值取自实体本身的属性。
如果您使用
<composite-id class="....">
<key-property=..../>
<key-property=..../>
</composite-id>
然后,指定的类将用作键属性的持有者。但是,实体类必须也具有这些属性 - 值存储在实体类和复合ID类中。实体类不知道密钥类。在我看来,不是很好。
有一个更好的第三种方法,在文档here中描述:
<composite-id name="id" class="OrderLineId">
<key-property name="lineId"/>
<key-property name="orderId"/>
<key-property name="customerId"/>
</composite-id>
此处,复合键由类OrderLineId
表示,其实例存储在实体类中的字段id
下。这使实体和密钥之间的分离更加清晰。
答案 2 :(得分: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>