Java Hibernate:脏检查和仅更新脏属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2674516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:40:40  来源:igfitidea点击:

Hibernate: Dirty Checking and Only Update of Dirty Attributes?

javahibernate

提问by jens

In the "good old JDBC days" I wrote a lot of SQL code that did very targeted updates of only the "attributes/members" that were actually changed:

在“旧的 JDBC 时代”中,我编写了很多 SQL 代码,这些代码只对实际更改的“属性/成员”进行了非常有针对性的更新:

For example, consider an object with the following members:

例如,考虑一个具有以下成员的对象:

public String name;
public String address;
public Date date;

If only datewas changed in some Business Method I would only issue an SQL UPDATEfor the datemember.

如果仅date在某些业务方法中更改,我只会UPDATEdate成员发出 SQL 。

It seems however (that's my "impression" of Hibernate) that when working with a standard Hibernate mapping (mapping the full class), even updates of only a single member lead to a full update of the object in the SQL statements generated by Hibernate.

然而,似乎(这是我对 Hibernate 的“印象”),在使用标准 Hibernate 映射(映射完整类)时,即使仅更新单个成员也会导致 Hibernate 生成的 SQL 语句中对象的完整更新。

My questions are:

我的问题是:

  1. Is this observation correct, that Hibernate does notintelligently check (in a fully mapped class), what member(s) where changed and then only issue updates for the specific changed members, but rather always will update (in the generated SQL Update Statement) all mapped members (of a class), even if they were not changed (in case the object is dirty due to one member being dirty...)

  2. What can I do to make Hibernate only update those members, that have been changed? I am searching for a solution to have Hibernate only update the member that actually changed.

  1. 这个观察是否正确,Hibernate不会智能地检查(在完全映射的类中),哪些成员发生了更改,然后只为特定更改的成员发出更新,而是总是会更新(在生成的 SQL 更新语句中)所有映射的成员(一个类),即使它们没有改变(如果对象因为一个成员变脏而变脏......)

  2. 我该怎么做才能让 Hibernate 只更新那些已更改的成员?我正在寻找一种解决方案,让 Hibernate 只更新实际更改的成员。

(I know Hibernate does quite some work on dirty-checking, but as far as I know this dirty checking is only relevant to identify if the object as whole is dirty, not what single member is dirty.)

(我知道 Hibernate 在脏检查方面做了很多工作,但据我所知,这种脏检查只与识别整个对象是否脏,而不是哪个成员是脏的。)

采纳答案by Maurice Perry

Actually, you can specify the options dynamic-updateand dynamic-insertin a class mapping. It does just that. More info here.

实际上,您可以在类映射中指定选项dynamic-updatedynamic-insert。它就是这样做的。更多信息在这里

回答by Arthur Ronald

Hibernate just update what you really want to

Hibernate只是更新您真正想要的内容

public class Person {

    private Integer id;

    public String name;
    public String address;
    public Date date;

    // getter's and setter's

}

And you do something like

你做类似的事情

Person person = (Person) sessionFactory.openSession().get(Person.class, personId);

person.setName("jean");

Hibernate is smart enough to know just name property has been changed. Although you can see your log as follows

Hibernate 足够聪明,只知道 name 属性已更改。虽然你可以看到你的日志如下

UPDATE PERSON (NAME, ADDRESS, DATE) VALUES (?, ?, ?);

Because Hibernate cache each SQL (INSERT, UPDATE, SELECT) query for EACH entity, again, it just update what you really want to.

因为 Hibernate 会缓存每个实体的每个 SQL(插入、更新、选择)查询,同样,它只会更新您真正想要的内容。

回答by Erik Hart

I think dynamic-update is good if you have heavy database load and one or multiple indexes to recreate on a full update (where all columns are updated, also those with unchanged values).

我认为如果你有很重的数据库负载和一个或多个索引要在完全更新时重新创建(所有列都被更新,还有那些值没有变化的列),我认为动态更新是好的。

Maybe some DBMS recognize if UPDATE sets an already existing value to not update an index including that column. But many seem to be too "stupid" to recognize this (or don't check that for performance reasons).

也许某些 DBMS 会识别 UPDATE 是否设置了一个已经存在的值以不更新包含该列的索引。但是许多人似乎太“愚蠢”而无法认识到这一点(或者出于性能原因不检查)。

Client side load for creating SQL queries is not a problem for most DB client applications. Interpretation of SQL in DB should take less time than recreating a big index.

对于大多数数据库客户端应用程序来说,用于创建 SQL 查询的客户端负载不是问题。在 DB 中解释 SQL 应该比重新创建一个大索引花费更少的时间。

Please correct me if I'm wrong!

如果我错了,请纠正我!

回答by user2250246

You can optimize dirty checking a lot by implementing interfaces like CustomEntityDirtinessStrategy or Interceptor. See working example at http://prismoskills.appspot.com/lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp

您可以通过实现 CustomEntityDirtinessStrategy 或 Interceptor 等接口来优化脏检查。请参阅http://prismoskills.appspot.com/lessons/Hibernate/Chapter_20_-_Dirty_checking.jsp 上的工作示例