是否对原始类使用某种字节码修改?
或者,也许 Hibernate 通过将给定对象与之前持久化的版本进行比较来获得脏状态?
我遇到了 hashCode()
的问题和 equals()
复杂对象的方法。如果对象有集合成员,我觉得计算哈希码会很慢,循环引用也是个问题。
如果 Hibernate 不使用 hashCode()
/equals()
要检查脏状态,我想我不应该使用 equals()
/hashCode()
对于实体对象(不是值对象),但我也担心如果相同的运算符( ==
)还不够。
所以,问题是:
Hibernate 如何知道对象的属性是否发生了变化?
您是否建议覆盖
hashCode()
/equals()
复杂对象的方法?如果它们包含循环引用怎么办?还有,
将
hashCode()
/equals()
只有id
场够了吗?
最佳答案
Hibernate 使用一种称为inspection 的策略,基本上是这样的:当从数据库加载一个对象时,它的快照会保存在内存中。当 session 被刷新时,Hibernate 将存储的快照与当前状态进行比较。如果它们不同,则将对象标记为脏,并将合适的 SQL 命令排入队列。如果对象仍然是 transient 的,那么它总是脏的。
来源:Hibernate in Action 一书(附录 B:ORM 实现策略)
值得注意的是,Hibernate 的脏检查独立于方法 equals/hascode。 Hibernate 根本不看这些方法(使用 java.util.Set 的时候除外,但这与脏检查无关,仅与 Collections API 相关)我前面提到的状态快照类似于值数组。将框架的这样一个核心方面留给开发人员将是一个非常糟糕的决定(老实说,开发人员不应该关心脏检查)。不用说,equals/hascode 可以根据您的需要以多种方式实现。我建议你阅读引用的书,那里作者讨论了 equals/hascode 实现策略。非常有见地的阅读。
关于java - Hibernate 如何检测实体对象的脏状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5268466/