当前位置: 首页 > 面试题库 >

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

樊飞飙
2023-03-14
问题内容

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

或者,也许Hibernate通过将给定的对象与以前保留的版本进行比较而得到脏状态?

我在使用复杂对象的hashCode()equals()方法时遇到问题。我觉得如果对象具有集合成员,则计算哈希码将非常慢,并且循环引用也是一个问题。

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

因此,问题是:

  1. Hibernate如何知道对象的属性是否已更改?

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

并且,

  1. hashCode()/ equals()只的id场够吗?

问题答案:

Hibernate使用一种称为 检查
的策略,该策略基本上是这样的:从数据库加载对象时,会将其快照保存在内存中。刷新会话后,Hibernate会将存储的快照与当前状态进行比较。如果它们不同,则将该对象标记为肮脏,并在适当的SQL命令中排队。如果物体仍然是瞬态的,那么它总是很脏。

资料来源:《行动中的hibernate》(附录B:ORM实施策略)

重要的是要注意,Hibernate的脏检查与equals / hascode方法无关
。Hibernate根本不查看这些方法(使用java.util.Set时除外,但这与脏检查无关,仅与Collections
API不相关)我前面提到的状态快照类似于值数组。将框架的这一核心方面留给开发人员是一个非常糟糕的决定(说实话,开发人员不应该在意脏检查)。不用说,equals
/ hascode可以根据您的需要以多种方式实现。我建议您阅读引用的书,在那里作者讨论equals / hascode的实现策略。非常有见地的阅读。



 类似资料:
  • 我在试验Eclipselink。我正在尝试更新数据库中的一个现有实体。JPA实体只有公共字段,字段使用JPA注释进行注释。代码使用加载实体。 代码创建JPA实体的实例,为实体的公共字段赋值,并调用EntityManager.merge(entity)方法。Eclipselink不更新数据库记录。我启用了log来查看Eclipselink是否发出SQL语句。 Eclipselink不发出任何upda

  • 我有一个使用和的Spring Boot应用程序。您可以在这个GitHub存储库中找到整个代码。 我的问题是,如何在没有任何外键的情况下,通过使用结构向特定列添加国际化功能? 例如,我想定义一个JPA实体,如下所示: 然后,对于和地区,列中的数据将按如下方式存储: 然后,当当前区域设置为Köln时,当设置为区域设置时,则在读取数据时获取数据! 此外,当我们存储数据时,传递的字符串以JSON格式存储在

  • 问题内容: 在“旧的JDBC美好时光”中,我编写了许多SQL代码,这些代码仅针对实际上已更改的“属性/成员”进行了针对性的更新: 例如,考虑具有以下成员的对象: 如果仅在某些业务方法中进行了更改,我将只为该成员发出一个SQL 。 但是,似乎(这是我对Hibernate的“印象”)在使用标准Hibernate映射(映射完整类)时,即使仅单个成员的更新也会导致Hibernate生成的SQL语句中对象的

  • 问题内容: 在Hibernate期间,我正在加载一些对象,由于延迟加载,其中一些对象已作为代理加载。一切正常,我不想关闭延迟加载。 但是稍后我需要通过RPC将一些对象(实际上是一个对象)发送到GWT客户端。碰巧这个具体对象是代理。所以我需要将其变成一个真实的对象。我在Hibernate中找不到类似“实现”的方法。 我如何才能将某些对象从代理变为真实,从而知道它们的类和ID? 目前,我看到的唯一解决

  • 假设我有一个项集合,例如,我需要检查是否有任何项从包装类中被修改,例如,任何项的属性的值通过setter被更改: 或者另一个问题,选择的答案建议使用标记,每次修改属性时都需要升起该标记。然而,我的类实际上会变得更脏,矛盾的是,我需要修改几十个修改Item属性的方法。 有没有其他方法,最好是透明的?

  • 问题内容: 我正在尝试设计一个非常简单的应用程序,并使自己与Hibernate的实体和值对象的定义(在Java Persistence with Hibernate的第4章中定义)有些困惑。 我所拥有的是带有客户的应用程序,可以下订单(一对多关系)。这些订单中的每一个都有许多订单行(也是一对多)。现在,我认为客户具有身份(客户编号),订单(订单编号)也是如此,因此它们是实体对象吗?我的困惑来自订单