考虑到我们有一个MyEntity
类,其中包含一些带有getter和setter的字段。此外,类EntityA
和EntityB
扩展了MyEntity
。 MyEntityA
中的某些字段不在MyEntityB
中,反之亦然。当我们谈论实体时,EntityA
和EntityB
确实有它们自己的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;
}
这样,同一具体类的对象将通过全套属性(包括通用和特定属性)进行比较,而不同类的实例将仅通过通用属性进行比较。尽管这是违反合同传递属性的非标准方式,但它可能会解决您的特定问题。