部分2.1.5 Hibernate 用户指南指出
In cases where you will be dealing with entities outside of a Session (whether they be transient or detached) ... you should consider implementing equals/hashCode.
忽略在集合(例如 Set)中使用这些实体的明显原因,我们希望或需要按照 hibernate 文档中的建议覆盖现有的 equals/hashcode 的其他情况是什么?
最佳答案
首先,实体平等是一个领域细节,最好从业务代码中抽象出来。显然,最好的地方是实体本身。此外,相等规则通常可能会根据实体状态或其他域规则而变化,因此重写 equals 方法可确保这些规则不仅在业务代码中得到遵守,而且在集合使用和 Hibernate 的 session 管理中也得到遵守。
考虑一个基于组合键的实体,它使用多个字段来构成相等性。以下哪项业务代码看起来更有吸引力并且更改起来最不严格:
public void someBusinessFunction(EntityA e1, EntityA e2) {
if(e1.equals(e2))
throw new SomeEqualityException();
// do logic
}
public void someBusinessFunction2(EntityA e1, EntityA e2) {
if(e1.getId().getFieldA().equals(e2.getId().getFieldA()) &&
e1.getId().getFieldB().equals(e2.getId().getFieldB()) &&
e1.getId().getFieldC().equals(e2.getId().getFieldC())) {
throw new SomeEqualityException();
}
// do logic
}
从业务代码的角度来看,我们不应该关心什么构成平等。代码只关心同一类的两个实例是否彼此相等。使用什么规则来确定用例是不相关的。
简而言之,通过抽象首先应该抽象的细节来实现良好的编程。
编辑
更具体地说,对于 Java 语言本身,Object
的普通相等性仅通过 ==
运算符比较两个操作数是否指向同一物理实例。仅当两个实例指向同一内存位置时,这才有效。
可以通过多个事务获取相同的域实体,因此会指向两个不同的内存位置,因为它们曾经由不同的 session 管理。在这种情况下,默认的 equals
方法将返回 false,这可能是不需要的。
通过重写 equals
方法,您可以显式确保上述情况始终返回 true
以获得相等性,无论实例如何获取以及存储在何处内存中。
此外,java 文档明确指出,当您重写 equals
以维护 hashCode
和 之间的契约时,应该重写
这样,当对象相等时,哈希码也相等。hashCode
equals
关于java - 为什么 session 之外的 Hibernate 实体应该实现 equals() 和 hashcode() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34533688/