Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate:脏检查和只更新脏属性?_Java_Hibernate - Fatal编程技术网

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

Java Hibernate:脏检查和只更新脏属性?,java,hibernate,Java,Hibernate,在“旧JDBC时代”,我写了很多SQL代码,只对实际更改的“属性/成员”进行了非常有针对性的更新: 例如,考虑一个具有下列成员的对象: public String name; public String address; public Date date; 如果在某些业务方法中只更改了date,我只会为date成员发出一个SQLUPDATE 然而,在使用标准Hibernate映射(映射完整类)时,即使只更新一个成员,也会导致Hibernate生成的SQL语句中对象的完整更新(这是我对Hiber

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

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

public String name;
public String address;
public Date date;
如果在某些业务方法中只更改了
date
,我只会为
date
成员发出一个SQL
UPDATE

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

我的问题是:

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

  • 如何使Hibernate只更新已更改的成员?我正在寻找一种解决方案,使Hibernate只更新实际更改的成员


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

    实际上,您可以在类映射中指定选项
    动态更新
    动态插入
    。它就是这样做的。更多信息。

    休眠只需更新您真正想更新的内容

    public class Person {
    
        private Integer id;
    
        public String name;
        public String address;
        public Date date;
    
        // getter's and setter's
    
    }
    
    你做了一些类似的事情

    Person person = (Person) sessionFactory.openSession().get(Person.class, personId);
    
    person.setName("jean");
    
    Hibernate足够聪明,只知道name属性已经更改

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

    因为Hibernate缓存每个实体的每个SQL(INSERT、UPDATE、SELECT)查询,所以它只更新您真正想要的内容。

    我认为动态更新是好的,如果您有大量数据库负载,并且在一次完整更新中需要重新创建一个或多个索引(其中所有列都会更新,也包括那些值不变的列)

    也许有些数据库管理系统会意识到更新是否设置了一个已经存在的值来不更新包含该列的索引。但许多数据库管理系统似乎太“愚蠢”而无法意识到这一点(或者出于性能原因而不检查这一点)

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


    如果我错了,请纠正我!

    通过实现CustomEntityDirtinesStrategy或Interceptor等接口,您可以大量优化脏检查。
    参见

    你好,莫里斯,非常感谢!!!你的帮助非常有用。我不知道“动态更新”在你的帮助下,我可以用谷歌搜索它,现在我完全知道如何解决我的问题。非常感谢!!!现在动态更新/动态插入已被弃用,因此你可以使用@DynamicUpdate/@DynamicInsert代替它你好,亚瑟,也感谢你的回答!!“动态更新”关键字确实解决了我的问题。谢谢!@jens你确定要使用动态查询吗???每次动态更新实例时,Hibernate都需要创建一个新的更新查询,而不是使用缓存的更新查询。请注意性能问题。谢谢你的回复。你当然是对的。通常我不会使用动态更新。B但在“多并发”环境中,我有一个非常特殊的要求,其中几个进程将更新记录/对象。但幸运的是,这些更新并不相关。进程a将始终更新列1、2,进程B将使用“动态更新”更新列3、4等我只能更新1,2或3,4而没有任何问题。但是,当我要用所有列1,2,3,4更新整个对象时,我必须引入版本控制并处理失败的更新…总的来说,你是绝对正确的。