java - Hibernate 如何检测实体对象的脏状态?

标签 java hibernate orm entity-relationship identity

是否对原始类使用某种字节码修改?

或者,也许 Hibernate 通过将给定对象与之前持久化的版本进行比较来获得脏状态?

我遇到了 hashCode() 的问题和 equals()复杂对象的方法。如果对象有集合成员,我觉得计算哈希码会很慢,循环引用也是个问题。

如果 Hibernate 不使用 hashCode()/equals()要检查脏状态,我想我不应该使用 equals()/hashCode()对于实体对象(不是值对象),但我也担心如果相同的运算符( == )还不够。

所以,问题是:

  1. Hibernate 如何知道对象的属性是否发生了变化?

  2. 您是否建议覆盖 hashCode()/equals()复杂对象的方法?如果它们包含循环引用怎么办?

    还有,

  3. 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/

相关文章:

java - 如何使用Math.pow查找整数数组的几何平均值

java - Sbt/Activator 未在 Play2 java 项目中运行所有测试

sql-server - MSSQL 架构和 Hibernate 5.1.0.Final(未找到表)

java - JBoss接缝: How to Open jpa/hibernate session in view

python - 这可以用 ORM 来完成吗? - Django

Java-如何让我的 TicTacToe 游戏正确检查获胜者?

java - 实现死锁条件

java - SQL 查询到 Hibernate ORM 查询

Django 模型 - 如何添加订单索引注释?

orm - 如何在 EntityManager (JPA) L1 或 L2 缓存大小中设置限制