2

This may be a very stupid question, but...

I'm using JPA 2.0 with Hibernate 4. I have a persistent object, with many fields.

I create and persist it in one transaction. Then, in another, I look that object up and change the value of one field on it:

try{
    tx.begin();
    MyObj object = myObjDAO.findById(objectId);
    object.setFieldA("Different value");
} finally {
    tx.commit();
}

JPA persists this change when the transaction commits, but I can see from my MySQL genquery.log that the update statement it generates involves all fields on the object:

439 Query
/* update uk.co.core.objects.MyObj */ update myobj set created='2012-03-06 13:39:37', modified='2012-03-06 13:39:37', version=1, fieldA='Different value', fieldB='originalValue', fieldC='originalValue' where id='objectId' and version=0; 439 Query commit

Why does it include all the unchanged fields and their existing values in the query, rather than just:

update myobj set fieldA='different value', version=1, modified='somedate' where id='objectId' and version=0;

It may not look like much of a difference on this example, but I have some objects with many more fields, all of which are included in their update statements.

Would it not be faster/more efficient, even if purely from a volume of string data perspective, to only include changed fields in the update query? If so, is there a configuration option to make it do so?

Hope you can help anyway, thanks!

Ben Kirby
  • 904
  • 2
  • 11
  • 29

3 Answers3

1

You can configure hibernate to exclude the unmodified fields in the update query as told in this article.

This is done by adding dynamic-update="true" in your class mapping.

<class ... table="your_table" .... dynamic-update="true">

In a large table with many columns (legacy design) or contains large data volumes, this will have a great impact on the system performance.

It can have some performance impact as told here. So measure the performance of your code before you implement it.

Read the API here for more information.

Community
  • 1
  • 1
ManuPK
  • 11,623
  • 10
  • 57
  • 76
1

To persist just the delta's your ORM would have to:

  1. Read the current version of your object, with all it's sub-entities, from the database.
  2. Iterate each attribute and compare their value to see if it has changed.
  3. Generate a specialized query just for updating the attributes that were changed.

That's significantly more complicated than just issuing a standard update across all columns, and would also be significantly less performant, due to the increased complexity.

Perception
  • 79,279
  • 19
  • 185
  • 195
  • a specialized a **HQL** is a good idea, when you know exactly what to update, regardless of the version. But am afraid your solution might be a **performance overhead as the object has to loaded to memory and then should be compared**. – ManuPK Mar 06 '12 at 14:37
0

Now discovered the danger of asking 2 questions in the same... question. Both ManuPK and Perception gave great, helpful, correct answers. However I received more info and understanding from ManuPk's, hence why I accepted it.

Definitely agree with him - setting the attribute should only be done for certain tables, and performance should definitely be tested before and after.

In future, I'll try to make my questions more targeted.

Ben Kirby
  • 904
  • 2
  • 11
  • 29