There is one ObjectOptimisticLockingFailureException thrown. I check the log and find this exception is triggered by a select query. This is werid.
Here is the exception stack trace.
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:317)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy117.countOtherRoles(Unknown Source)
at net.homecredit.mcd.app.service.UserRolePosService.countOtherRoles(UserRolePosService.java:315)
at net.homecredit.mcd.app.service.UserRolePosService.canRemoveEmployer(UserRolePosService.java:375)
at net.homecredit.mcd.app.service.UserRolePosService.deactivate(UserRolePosService.java:339)
at net.homecredit.mcd.app.service.UserRolePosService.fillRoleData(UserRolePosService.java:241)
at net.homecredit.mcd.app.service.UserRolePosService.fillRoleData(UserRolePosService.java:199)
at net.homecredit.mcd.app.service.UserRolePosService.fillRoleData(UserRolePosService.java:180)
at net.homecredit.mcd.app.service.pos.PosBusinessService.saveUserRole(PosBusinessService.java:224)
at net.homecredit.mcd.app.service.pos.PosBusinessService.updatePos(PosBusinessService.java:121)
at net.homecredit.mcd.app.service.pos.PosBusinessService$$FastClassBySpringCGLIB$$ad825d06.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:69)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at net.homecredit.mcd.common.security.ForbiddingSecurityInterceptor.invoke(ForbiddingSecurityInterceptor.java:17)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at net.homecredit.mcd.common.aop.AuditInterceptor.invoke(AuditInterceptor.java:21)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
at net.homecredit.mcd.app.service.pos.PosBusinessService$$EnhancerBySpringCGLIB$$7cfba5de.updatePos(<generated>)
at net.homecredit.mcd.app.service.homesis.kafka.HsisKafkaConsumer.updatePos(HsisKafkaConsumer.java:122)
at net.homecredit.mcd.app.service.homesis.kafka.HsisKafkaConsumer.updatePos(HsisKafkaConsumer.java:97)
at net.homecredit.mcd.app.service.homesis.kafka.HsisKafkaConsumer.consumePos(HsisKafkaConsumer.java:73)
at sun.reflect.GeneratedMethodAccessor871.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:180)
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:112)
at org.springframework.kafka.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:48)
at org.springframework.kafka.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:174)
at org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:82)
at org.springframework.kafka.listener.adapter.RecordMessagingMessageListenerAdapter.onMessage(RecordMessagingMessageListenerAdapter.java:50)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeRecordListener(KafkaMessageListenerContainer.java:975)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.doInvokeWithRecords(KafkaMessageListenerContainer.java:959)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeRecordListener(KafkaMessageListenerContainer.java:901)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.invokeListener(KafkaMessageListenerContainer.java:786)
at org.springframework.kafka.listener.KafkaMessageListenerContainer$ListenerConsumer.run(KafkaMessageListenerContainer.java:656)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [net.homecredit.mcd.app.domain.Pos#2307536273]
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2400)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3202)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3077)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3457)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:145)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:589)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:463)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:50)
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1398)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1483)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1445)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1414)
at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1463)
at net.homecredit.mcd.app.dao.UserRolePosDao.countOtherRoles(UserRolePosDao.java:225)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
... 47 common frames omitted
The log shows it encounters a optimistic lock error while updating the POS table. This line
"at net.homecredit.mcd.app.dao.UserRolePosDao.countOtherRoles(UserRolePosDao.java:225)"
, triggers this optimistic error. I check this code.
public Integer countOtherRoles(User user, UserRolePos userRole) {
return em.createNamedQuery(UserRolePos.COUNT_OTHER_ROLE_FOR_USER, Long.class)
.setParameter("user", user)
.setParameter("userRole", userRole)
.getSingleResult().intValue();
}
Related query is as below
@NamedQuery(name = UserRolePos.COUNT_OTHER_ROLE_FOR_USER,
query = "SELECT COUNT(urp) FROM UserRolePos urp " +
"WHERE urp.user = :user " +
"AND urp != :userRole "
)
It is just a select query with another UserRole table, why this trigger the optimistic lock error with POS table?
If you look closely in the stacktrace, you will notice that Hibernate does "auto-flushing". This happens when you have "dirty" entities in your persistence context and try to do a query that uses tables, which intersect with the tables of the dirty entities. If it wouldn't flush the dirty entries, you might get wrong results.