为具有生成ID的实体实现equals()时的最佳实践是什么

时间:2010-12-01 10:15:56

标签: java hibernate

如果我有一个包含A,B,C,D列的表格   
答:自动生成的id(PK)   
B& C:组合必须是唯一的(这些是在商业意义上实际定义身份的列)   
D:其他一些专栏

现在,如果我将基于此表创建业务对象(例如,在Java中),哪一个是equals()方法的更好实现:

  1. 基于A
  2. 定义相等性
  3. 基于B和C定义相等
  4. 或者,我选择哪一个并不重要。

3 个答案:

答案 0 :(得分:20)

绝对是B和C,因为即使在实体持久化之前,您希望equals()合同有效。你说自己:

  

这些是实际的列   在商业意义上定义身份

如果是这种情况,那么逻辑equals()应该使用。数据库密钥是数据库的关注点,应该与业务层无关。

并且不要忘记在hashcode()中使用相同的属性。

答案 1 :(得分:3)

我同意@ S.P.Floyd。但我想补充一点。

有些实体没有唯一的业务属性。例如,实体可能只有A(PK)和B(商业财产),但许多实体具有相同的B值。

在这种情况下,很难创建equals()hashcode()。您当然不希望将它们基于A,因为您无法将持久对象与尚未持久化的对象进行比较。并且你不能仅仅基于B,因为那时许多不同的唯一实体的对象看起来是相同的。

在这些情况下我做的是Date created = new Date();属性。创建实体时,它会自动获取创建的时间戳。在我的equals()hashcode()中,我同时包含Bcreated。这并不完美,因为很有可能同时创建两个对象(特别是在集群解决方案中),但这是一个开始。如果必须,请添加UID或其他生成的非数据库PK的业务属性。

答案 2 :(得分:2)

如果(B,C)是唯一对,则不需要自动生成的id。对于表格,A等价于(B,C)(一对一关系)。

你可能想要或需要额外的密钥,但我同意seanizer,使用(B,C)表示equals,因为A是冗余的(并且在保持对象之前null),不要使用for equals(和hashcode)