25

So I understand what setting this attribute dynamic-update=true does, i.e it considers only those fields that were modified and omits the job of setting null values for other fields. Saving an overhead, good on performance.

Asking out of curiosity: How does hibernate come to know what all fields were modified? Does it do a comparison of the result generated by the select query to the database first before firing an update query? Assuming yes, then isn't comparison an overhead to performance?

Correct me if I'm wrong. Thanks in advance!

robot_alien
  • 955
  • 2
  • 13
  • 30
  • 1
    What's strange? I was searching on this issue, found two similar questions, the one in the link and this one. I've looked at the dates and your came after, otherwise I'd flagged the other one. What's the problem? It's just a flag as duplicate, not a downvote or an offence. – Spock May 12 '17 at 11:02

2 Answers2

41

So after almost 2 month's wait I was finally able to derive this conclusion proposed as an answer to my own question with the help from various sources:

1.) When using dynamic-update, Hibernate has to generate the corresponding SQL string each time and there is thus a performance cost on the Hibernate side. In other words, there is a trade-off between overhead on the database side and on the Hibernate side.

2.) Hibernate caches the actual SELECT, INSERT and UPDATE SQL strings for each entity. This results in not having to re-create these statements every time you want to find, persist or update an entity.However, when using dynamic-update, Hibernate has to generate the corresponding SQL strings each time. This results in a performance cost on the Hibernate side.

3.) Useful when applied to a very small & simple table as there is a significant performance gain using this annotation. A more realistic scenario, on wider tables using a remote database, performance increases may be more pronounced. Of course, the mileage you get out of this will vary most of the columns need to be updated.

4.) The @DynamicUpdate annotation/ dynamic-update=true is used to specify that the UPDATE SQL statement should be generated whenever an entity is modified. By default, Hibernate uses a cached UPDATE statement that sets all table columns. When the entity is annotated with the @DynamicUpdate annotation, the PreparedStatement is going to include only the columns whose values have been changed.

Overall could be summarized as:

  1. Runtime SQL generation overhead.
  2. No PreparedStatement(caching) used anymore.
  3. Performance overhead.

Credits: Hibernate ORM 5.2.7.Final User Guide,http://memorynotfound.com/hibernate-dynamic-update-attriburte-example/ , https://stackoverflow.com/a/3405560/1004631

P.S.: Also holds true for dynamic-insert=true/ @DynamicInsert annotation

robot_alien
  • 955
  • 2
  • 13
  • 30
  • 1
    1), 2), and 4) are the same thing, 3) is very vague. Also, the summary is not correct (why would no prepared statement be used for this flag?). – Lukas Eder Jun 30 '17 at 15:21
  • I'm looking also for the answer to this question, in my opinion this particular answer doesn't cover what was the main question. Point 4) gets closer to a real answer but not quite... – dacuna Apr 18 '18 at 01:21
  • 2
    hmm, generating a string based on only the updated columns vs. updating N number of columns in the database. I will take my chances on the reduced update statement. Especially when you have update triggers that do things when you update columns in the database. – nurettin Oct 11 '18 at 12:55
  • My question is why Hibernate by default updates all the fields? Somehow update on a specific field is more complicate to implement than on all fields even unmodified? – Andrey M. Stepanov Jan 06 '22 at 23:40
  • And why to use DynamicUpdate annotation if Modifying annotation does exactly the same? – Andrey M. Stepanov Jan 06 '22 at 23:43
5

So, from what I understood, the dynamic-insert=true, makes SQL not include modified properties.

Example: if you are gonna update [name] attribute from a row in the table [User] and dynamic-insert is set to true, then the SQL generated will be something around this:

update
    USER
set
    NAME="Example" 
where
    USER_ID=1

Else, if dynamic-insert is set to false, the follwoing SQL will be generated:

update
    USER
set
    NAME="Example" 
    AGE = ??
    ADDRESS = ??
    PHONE = ??
where
    USER_ID=1
Joel
  • 7,401
  • 4
  • 52
  • 58
Pedro Figueiredo
  • 2,304
  • 1
  • 11
  • 18