Tuesday, December 29, 2009

Hibernate3 Tip#2: Enable Automatic Dirty Checking

In database parlance, when you read a record from a table and update some of its fields in memory, the record is considered dirty. Dirty checking avoids unnecessary database write actions by performing SQL updates only on the modified fields of persistent objects. Hibernate3 JPA can do automatic dirty-checking for you via an annotation to the entity:
@org.hibernate.annotations.Entity(
dynamicInsert=true, dynamicUpdate=true
)
The dynamicInsert property is really only necessary to prevent writing NULL values to database fields. But if the changes involve setting NULL values (bad practice), you should probably turn it off.
I can think of three possible implementations for dirty checking:
  1. Caching a clean copy of the record and maintaining an edit copy of the persistent object. When an SQL update is due, the copies are compared and changes extracted from the edit copy for update. Obviously memory-intensive as 2 copies of a record are maintained at all times.
  2. Keeping track of which fields changed.
  3. Doing a SQL query just before updating and doing the necessary reductions to determine what changed.
I do not know which strategy Hibernate3 uses. Either way, the performance hit is minimal compared to rewriting whole table rows in the database - depending on how many fields each record has. It is recommended when you have more than 50 fields where any given update affects less than 25% of the fields (if you want hard numbers).