I have a java project that runs on a webserver. I always hit this exception.
I read some documentation, and found that pessimistic locking (or optimistic, but I read
I know this is an old question, but some of us are still hitting it and look at sky wandering how. Here is one kind of issue that I faced,
We have a queue manager that polls data and give to handlers for processing. To avoid picking up the same events again, the queue manger locks the record in database with a LOCKED state.
void poll() {
record = dao.getLockedEntity();
queue(record);
}
this method wasn't transactional but dao.getLockedEntity()
was transactional with 'REQUIRED'.
All good and on the road, after few months in production, it failed with optimistic locking exception,
After lots of debugging and checking in details we could find out that some one has changed the code like this,
@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
void poll() {
record = dao.getLockedEntity();
queue(record);
}
So the record was queued even before the transaction in dao.getLockedEntity() get committed (it uses the same transaction of poll method) and the object was changed underneath by the handlers (different threads) by the time the poll() method transaction get comitted.
We fixed the issue and it looks good now.
I thought of sharing it, because optimistic lock exception can be confusing and are difficult to debug. Some one might get benefited from my experience.
Regards Lyju
I had the same problem and in my case the problem was missing and/or incorrect equals implementation on some types of fields in the entity object. At commit time, Hibernate checks ALL entities loaded in the session to check if they are dirty. If any of the entities are dirty, hibernate tries to persist them - no matter of the fact that the actual object that is requested a save operation is not related to the other entities.
Entity dirtiness is done by comparing every property of given object (with their equals methods) or UserType.equals
if property has an associated org.Hibernate.UserType
.
Another thing that surprised me was, in my transaction (using Spring annotation @Transactional
), I was dealing with a single entity. Hibernate was complaining about some random entity that's unrelated to that entity being saved. What I realized is there is an outermost transaction we create at REST controller level, so the scope of the session is too big and hence all objects ever loaded as part of request processing get checked for dirtiness.
Hope this helps someone, some day.
Thanks Rags
I was also receiving such an exception, but the problem was in my Entity identifier. I am using UUID
and there are some problems in the way Spring works with them. So I just added this line to my entity identifier and it began working:
@Column(columnDefinition = "BINARY(16)")
Here you can find a little bit more information.
Just in case someone checked this thread and had the same issue as mine...
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
I'm using NHibernate, I receive same error, during creating an object...
I was passing the key manually, and also specified a GUID generator in mapping, so hibernate generate same exact error for me, so once I removed the GUID, and left the field empty, everything went just fine.
this answer may not help you, but will help someone like me, who just your thread becasue of same error
I had the same problem in my grails project. The Bug was, that i overwrite the getter method of a collection field. This returned always a new version of the collection in other thread.
class Entity {
List collection
List getCollection() {
return collection.unique()
}
}
The solution was to rename the getter method:
class Entity {
List collection
List getUniqueCollection() {
return collection.unique()
}
}