views:

321

answers:

2

I have a problem where I want to read an object from the database using Hibernate, change a value, and save the object. If changing the value takes some time, what's the best way to ensure the underlying object in the database has not changed? I am doing this in one transaction (and one session).

The code looks something like:

// Load from DB

Criteria crit = session.createCriteria( Dummy.class ).add( Restrictions.eq("id", 5) );

Dummy val = crit.uniqueResult();

// Processing time elapses.

// Update value of dummy.

val.x++;

// Save back to database. But what if someone modified the row with ID  = 5 in the meantime, and changed the value of x?

session.saveOrUpdate( val );
A: 

You can use pessimistic lock although I wouldn't do that, but it may be useful in your case.

Since your object is retrieved from the DB you have to lock the DB so no one else modifies your object while you're working with it.

To do that you should lock your object.

session.lock( myObject , LockMode.UPGRADE );

Give it a try.

EDIT

This may be more you:

// Load from DB

Criteria crit = session.createCriteria( Dummy.class ).add( Restrictions.eq("id", 5) );

crit.setLockMode( LockMode.UPGRADE  ); // issues a SELECT ... for UPDATE... 

Dummy val = crit.uniqueResult();

 etc.etc

Criteria.setLockMode()

OscarRyz
The problem with the LockMode.UPGRADE occurs when there is no value returned (ie, no row with ID 5). So my program might want to insert its own new row, but what if another thread inserts into the table in the meantime?
Michal
Michal. This is what you're saying: "How can I lock a record that doesn't even exists on the database and prevent someone else insert it?"Read it until you find the problem with such statement.
OscarRyz
+2  A: 

I'd recommend optimistic locking instead. you add a "version" property to your object and then hibernate does an update operation at the end and verifies that the version has not changed since you read the object. generally a much better design than pessimistic locking (nothing like finding those db deadlocks!).

Of course, the question remains, what do you plan on doing if the object has changed?