Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change Hibernate´s auto persistance strategy

I just noticed that Hibernate entities are automatically persisted to the database (or at least to cache) before I call any save() or update() methods. To me this is a pretty strange default behavior — but ok, as long as I can disable it, it's fine.

The problem I have is that I want to update my entity's state (from a state "1" to state "2") only if the entity in the database still has the state it had when I retrieved it (state "1"). This is to eliminate concurrency issues when another server is updating this same object. For this reason, I have created a custom NamedQuery that will only update the entity if it is in the expected state "1". Here is some pseudo-code:

// Get the entity
Entity item = dao.getEntity(); 
item.getState(); // == 1

// Update the entity
item.setState(2); // Here is the problem, this effectively changes the
                  // state of my entity breaking my query that verifies
                  // that state is still == 1.

dao.customUpdate(item); //Returns 0 rows changes since state != 1.

How do I make sure the setters don't change the state in cache/db?

like image 256
Kristofer Avatar asked Jan 26 '26 15:01

Kristofer


1 Answers

Hibernate has built in support for what you are aiming to achieve - it supports optimistic locking using version ids or timestamps. If you try to save an object and the underlying data has changed, hibernate throws an exception. You can catch this exception and handle as necessary - ignore the update, retry or whatever makes sense.

See Optimistic Concurrency Control

EDIT: I'm not clear on how your update query works, but if you want to continue doing this by hand, you can evict your object from the session after retreiving it. This gives you a snapshot of the object as it was at retrieval time that you can modify independent from the db/cache. You can pass it into your custom update query as one side of the comparison, the other side being the persisted value. When the query selects/updates the entity, it will be re-read from the database, not from your evicted object. Your update query can then compare this with your evicted/modified value (passed as a parameter) to see if the update should be done or not.

See Session.evict()

like image 68
mdma Avatar answered Jan 29 '26 05:01

mdma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!