Hello, I am trying to upgrade from Spring Boot 3.3.3 to 3.4.0 and, without changing any code, an error started occurring when saving an entity to the database.
I have a CrudRepository (in Kotlin) like this:
@Repository
@Transactional
interface UploaderRepository: CrudRepository<Uploader, String> {
fun findByEmailAddress(email: String): Uploader?
fun findByUuid(uuid: String): Uploader?
fun deleteByUuid(uuid: String)
}
and a service (in kotlin) like this:
@Service
class UploadService(private val uploaderRepository: UploaderRepository) {
fun getOrCreateUploader(emailAddress: String): Uploader =
uploaderRepository.findByEmailAddress(emailAddress)
?: uploaderRepository.save(Uploader(emailAddress = emailAddress))
}
But when getOrCreateUploader
is executed I get this error:
org.springframework.orm.ObjectOptimisticLockingFailureException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.bright.externaluploader.model.Uploader#]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:325) ~[spring-orm-6.2.0.jar:6.2.0]
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244) ~[spring-orm-6.2.0.jar:6.2.0]
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:560) ~[spring-orm-6.2.0.jar:6.2.0]
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-6.2.0.jar:6.2.0]
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:343) ~[spring-tx-6.2.0.jar:6.2.0]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:160) ~[spring-tx-6.2.0.jar:6.2.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.0.jar:6.2.0]
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165) ~[spring-data-jpa-3.4.0.jar:3.4.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.0.jar:6.2.0]
at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:96) ~[spring-data-commons-3.4.0.jar:3.4.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.0.jar:6.2.0]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.0.jar:6.2.0]
at jdk.proxy2/jdk.proxy2.$Proxy150.save(Unknown Source) ~[na:na]
at [...]UploadService.getOrCreateUploader(UploadService.kt:64) ~[main/:na]
I've checked the release notes for 3.4.0 and I can't find any changes in this area. Does anyone know what's going on? Thanks!
Comment From: philwebb
This is unlikely to be an issue in Spring Boot itself, the most likely cause would be something that's changed in Hibernate. You could start by trying to downgrade your Hibernate version to 6.5.3.Final (the version used in Spring Boot 3.3.x) to see if the problem still occurs.
If it does, then I would suggest asking on stackoverflow.com or the Hibernate forums to see why the error is being thrown. A minimal sample that reproduces the issue would probably also help you get useful answers.
Comment From: anabright
For those interested, someone already posted about a similar issue in the Hibernate forums, so I've replied with my example there: https://discourse.hibernate.org/t/facing-with-objectoptimisticlocking-failureexception-after-migrating-to-hibernate-6-6-2-final/10725/5