考虑到我们有一个MyEntity类,其中包含一些带有getter和setter的字段。此外,类EntityAEntityB扩展了MyEntityMyEntityA中的某些字段不在MyEntityB中,反之亦然。当我们谈论实体时,EntityAEntityB确实有它们自己的equals方法,如下所示

@Override
public boolean equals(Object other) {
    if ((this == other))
        return true;
    if ((other == null))
        return false;
    if (!(other instanceof EntityA))
        return false;
    EntityA castOther = (EntityA) other;

    return ((this.getId() == castOther.getId()) || (this.getId() != null && castOther.getId() != null && this.getId().equals(castOther.getId())));
}


equals方法适用于休眠以标识唯一实体。

现在,我想将EntityA的实例与EntityB的实例进行比较。如果MyEntity中的所有字段都匹配,我将它们定义为相同。

为了进行检查,我让eclipse为我生成了equals方法并将其复制到类似isEqualWithRegardsToContent(MyEntity other)的方法中。

我看到这种方法有一个大问题:
如果有人曾经向任一实体添加新列并且不更新isEqualWithRegardsToContent(MyEntity other)方法,那么就会出现问题:实体在内容方面可能被认为是平等的,尽管事实并非如此。

我看不到单元测试会在这里有所帮助。

您有最佳做法吗?

最佳答案

假设您在超类中具有equals()方法,该方法可比较常见属性。

在子类equals()中,您可以首先调用super.equals(),然后,如果被比较的对象也属于此类,则仅比较特定的属性。因此,在EntityA中,您可以编写:

@Override
public boolean equals(Object o) {
    boolean eq = super.equals(o);
    if (eq && o instanceof EntityA) {
        EntityA e = (EntityA) o;
        return Objects.equals(this.propOne, e.propOne)
            && Objects.equals(this.propTwo, e.propTwo)
            && // compare other properties
    } else
       return eq;
}


这样,同一具体类的对象将通过全套属性(包括通用和特定属性)进行比较,而不同类的实例将仅通过通用属性进行比较。尽管这是违反合同传递属性的非标准方式,但它可能会解决您的特定问题。

10-08 18:57