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

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

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

  1. 基于A定义相等性
  2. 基于B和C定义相等性

或者,我选择哪两个并不重要。

肯定是B和C,因为你希望equals()契约在实体被持久化之前是有效的。 你说自己:

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

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

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

我同意@SPFloyd。 但我想补充一点。

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

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

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

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

您可能需要或需要额外的密钥,但我同意seanizer,使用(B,C)for equals并且因为A是冗余的(并且在对象被持久化之前为null ),不要将它用于equals(和hashcode)