18

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:

For example, consider an object with the following members:

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

If only date was changed in some Business Method I would only issue an SQL UPDATE for the date member.

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.

My questions are:

  1. Is this observation correct, that Hibernate does not intelligently 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.

(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.)

Daniel Serodio
  • 4,229
  • 5
  • 37
  • 33
jens
  • 269
  • 1
  • 4
  • 6

4 Answers4

18

Actually, you can specify the options dynamic-update and dynamic-insert in a class mapping. It does just that. More info here.

Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
Maurice Perry
  • 32,610
  • 9
  • 70
  • 97
  • Hello Maurice, thank you very much!!! Your help was absolute helpfull. I was not aware of the "dynamic-update" feature and with your help I could google for it and now I absolutely know how to solve my problem. Thanks very very much!!! – jens Apr 21 '10 at 07:15
  • 1
    Now dynamic-update/dynamic-insert is deprecated so you can use @DynamicUpdate/@DynamicInsert instead – Abdelghani Roussi Aug 13 '15 at 20:30
5

Hibernate just update what you really want to

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

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.

Arthur Ronald
  • 33,349
  • 20
  • 110
  • 136
  • Hello Arthur, thank you too for your answer!! The "dynamic-update" Keyword is really what solves my problem. Thanks ! – jens Apr 21 '10 at 07:17
  • @jens Are you sure you want to use dynamic-query ??? Each Time you *dynamic-update* your instance, Hibernate needs to create a new update query *instead of use a cached update query*. Be aware of performance issues. – Arthur Ronald Apr 21 '10 at 14:54
  • 1
    thank for your reply. You are of course right. Normally I will not use dynamic-upate. But I have a very special requirement in an "Multi Concurrent" Environment where several Processes will update the Record/Objet. But to my luck the upates are not related. Process A will always upate Columns 1,2 and Process B will update Columns 3,4 etc... By using "dynamic-updates" I can only update 1,2 OR 3,4 without any problems. However when I would update the whole object with all Columns 1,2,3,4 I would have to introduce Versioning and handle the failed updates... In general you are absolutely right. – jens Apr 21 '10 at 18:10
2

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

user2250246
  • 3,807
  • 5
  • 43
  • 71
0

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).

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.

Please correct me if I'm wrong!

Erik Hart
  • 1,114
  • 1
  • 13
  • 28