brenuart wrote:
This is not a bug at all. You have two different threads, accessing and modifing the same data. To avoid potential problems, you need a way to synchronize them.
Hibernate is of course not aware of this (how could it be anyway) - so you have to find another way yourself.
Either you use the database as sycnhronisation point (using a lock) or you do it yourself in your own code...
Er, no. This is not a synchronization issue. There's one session per thread. Overwrites of data in the database are prevented using Hibernate's optimistic lock implementation.
The problem is that when one thread gets a StaleObjectException, this should be recoverable. It should not be necessary for that thread to rollback and then remake all the changes made up to that point, because there has been no SQLException - there is no problem with the connection or with the transaction. However, because the update statement that causes the StaleObjectException is not removed from the session, the next time the session is flushed, you get the StaleObjectException again. It would be nice if either Hibernate removed the offending statement when the StaleObjectException occurrs, or even for the Session.evict() to remove not only the object from the entity cache, but also from the various statement caches.
To be clear: this is not due to transaction isolation, or proper demarcation of transactions, or synchronization of Java threads.
This is a question of what Hibernate is supposed to do and how it is supposed to be used: if there is an exception, should the session be thrown away? If so, why isn't the session flagged as being unusable? Then every method on it can assert the session is valid before continuing? In any case, if it should be thrown away, why is that necessary when we know that a condition can be recovered from?