Spring Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
Well, finally I've found a solution. Better say workaround.
The problem is in the way spring uses UUID
as entity identifier.
So there are two workarounds, solving this issue:
- first, you can change your id field type to other one, such as
Long
, for example, if it's possible to you; - or you can add this annotation to your
uuid
field:@Column(columnDefinition = "BINARY(16)")
.
The last solution I've found from this question.
Related videos on Youtube
Comments
-
Kamo Spertsian almost 2 years
I can't understand, what's wrong with my Service. I receive
org.hibernate.StaleObjectStateException
trying to run this method:fun updateNameForPhone(phone: String, name: String): Client { val res = clientRepository.findByPhone(phone) ?: throw ClientNotFoundException(phone) res.name = name return clientRepository.save(res) }
ClientRepository:
@Repository interface ClientRepository : JpaRepository<Client, UUID> { fun findByPhone(phone: String): Client? }
Client entity:
@Entity data class Client( var name: String = "", var phone: String = "", @Id @GeneratedValue(strategy = GenerationType.AUTO) val uuid: UUID = defaultUuid() )
Exception:
Object of class [com.app.modules.client.domain.Client] with identifier [12647903-7773-4f07-87a8-e9f86e99aab3]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.app.modules.client.domain.Client#12647903-7773-4f07-87a8-e9f86e99aab3]"
What is the reason? I'm using Kotlin 1.3.11, Spring Boot 2.1.1, MySql. I don't run it in different threads, just trying with single request.
-
Ankur over 5 yearscan you share how have you defined the transaction here?
-
Ankur over 5 yearsAlso, it would be helpful to have database table structure as well
-
Simon Martinelli over 5 yearsYou get a optimistic lock exception but I don't see that you are using a version field. Can you please post the whole code?
-
Kamo Spertsian over 5 years@simonmartinelli I have no version field, it has not yet been necessity.
-
Kamo Spertsian over 5 years@ankur No transaction and table creations myself, it's incapsulated by Spring. I just tag my Client class with Entity annotation. Service method is called from Controller. There is no interesting code there.
-
Ankur over 5 yearsHere is what i think is the problem: clientRepository.findByPhone(phone) is taking place under transaction T1 while clientRepository.save(res) is taking place under transaction T2. since, your
res
object is part of 2 different transactions, you are facing this issue. Have you used @Transactional anywhere in your code? -
Kamo Spertsian over 5 years@Ankur Controller's method, which calls service method, is annotated as
Transactional
, but I've deleted this annotation from there and nothing've changed. -
Kamo Spertsian over 5 yearsThe problem disappears when I change the table identifier type from
UUID
toLong
.. Looks like something is wrong with UUID and Spring communication.. Btw Long ids are not suitable for me, so I am trying to solve this problem.
-