并发更新期间的Hibernate StaleObjectStateException [英] Hibernate StaleObjectStateException during Concurrent Updates

查看:74
本文介绍了并发更新期间的Hibernate StaleObjectStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Java J2EE Web应用程序中使用Hibernate 3.5.2和Spring Core 3.0.1。当单独的用户同时更新相同的记录时,我得到一个StaleObjectStateExcpetion。事务由javax.persistence.EntityManager管理。以下是我创建该问题的步骤。


  1. 用户1登录到应用程序中

  2. 用户2登录到应用程序
  3. 用户1开始编辑记录A

  4. 用户2开始编辑记录A

  5. 用户1保存记录A

  6. 用户2保存记录


  7. $抛出org.hibernate.StaleObjectStateException b
    $ b

    我已经读过,这是由于数据库中的更新版本号与当前在该内存中的特定实体的版本号之间的差异引起的。但是,当我尝试使用查询或使用EntityManager.find()方法从数据库中获取最新信息来查找数据库中的当前版本号时,我发现版本号中没有区别。我也试图手动合并旧实体和新实体之间的变化,并且没有运气的情况下使用entityManager.merge(object)方法。关于如何解决这个问题的任何想法?

      13290 [http-8080-7] ERROR org.hibernate.event.def。 AbstractFlushingEventListener  - 无法使数据库状态与会话
    同步org.hibernate.StaleObjectStateException:行被另一个事务更新或删除(或未保存值映射不正确):[edu.pitt.nmrl.med.domain.medical。医疗史#362]
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1934)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2578)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2478)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2805)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:114)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
    在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
    在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:180)
    在org.hibernate.event.def .AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:64)
    at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl .java:1175)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1251)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    。在org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:241)在org.hibernate.ejb.criteria.CriteriaQueryCompiler $ 3.getResultList
    (CriteriaQueryCompiler.java:260)
    在edu.pitt .nmrl.med.services.SurveyService.checkMedicalDup(SurveyService.java:613)
    at edu.pitt.nmrl.med.services.SurveyService.save(SurveyService.java:790)
    at edu.pit t.nmrl.med.services.SurveyService $$ FastClassByCGLIB $$ b6424505.invoke(< generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    在org.springframework.aop.framework.Cglib2AopProxy $ CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
    在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    。在组织.bringframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop .interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    在org.springframework.aop.framework.Cglib2AopProxy $ DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
    at edu.pitt.nmrl.med.services.SurveyService $$ EnhancerByCGLIB $$ 5831613c.save(< generated>)$ b $ at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    在java.lang.reflect.Method.invoke(方法。的java:在org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:328 597)

    。在org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:273)
    在org.jboss.el.parser.AstMethodSuffix.getValue(AstMethodSuffix.java:59)
    在org.jboss.el.parser.AstMethodSuffix.invoke(AstMethodSuffix.java:65)
    at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
    at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
    at com.sun.facelets .el.TagMethodExpression.invoke(TagMethodExpression.java:68)
    a t javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component .UICommand.broadcast(UICommand.java:387)
    在javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:475)
    在javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java :756)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)$在com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)b
    $ b。在com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:18)
    。在com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.renderCycle(ReceiveSendUpdates.java:132)
    在com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.service(ReceiveSendUp date.java:74)
    at com.icesoft.faces.webapp.http.core.RequestVerifier.service(RequestVerifier.java:31)
    at com.icesoft.faces.webapp.http.common。 standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
    at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
    at com.icesoft.faces。 webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
    at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:53)
    at com。 icesoft.faces.webapp.http.servlet.SessionVerifier.service(SessionVerifier.java:26)
    at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
    。在com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:131)在javax.servlet.http.HttpServlet.service
    (HttpServlet.java:717)
    。在com.icesoft.faces.webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:56)
    在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)

    在org.springframework .security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:343)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    at org .springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    在org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
    在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    在org.springframework.security.web.session.Sessi onManagementFilter.doFilter(SessionManagementFilter.java:100)
    at org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication。 AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)维持在org.springframework.security.web.servletapi org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)

    。 SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)维持在org.springframework.security.web.savedrequest org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)

    。 RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    at org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentic ation.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)维持在org.springframework.security org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)

    。 web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)维持在org.springframework.security org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)

    。 web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework。 security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)维持在org.springframework org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)

    。 security.web。 FilterChainProxy.doFilter(FilterChainProxy.java:149)
    在org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    在org.springframework.web.filter.DelegatingFilterProxy.doFilter( DelegatingFilterProxy.java:167)在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235

    在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233 206)

    在org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)$ b在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    $ b在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    。在组织.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    在org.apache.catalina.connector.CoyoteAda pter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler。进程(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint $ Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread。 java:619)
    Jan 23,2012 12:07:16 PM com.sun.faces.application.ActionListenerImpl processAction
    SEVERE:javax.persistence.OptimisticLockException
    javax.faces.el.E​​valuationException :在javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)javax.persistence.OptimisticLockException

    在com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:387)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:475)
    at javax.faces 。C omponent.UIViewRoot.processApplication(UIViewRoot.java:756)
    处com.sun.faces.lifecycle.Phase com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
    。 doPhase(Phase.java:100)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor。申请(JsfLifecycleExecutor.java:18)
    处com.icesoft.faces.webapp.http com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.renderCycle(ReceiveSendUpdates.java:132)
    。 core.ReceiveSendUpdates.service(ReceiveSendUpdates.java:74)
    位于com.icesoft.faces.webapp.http.core.RequestVerifier.service(RequestVerifier.java:31)
    位于com.icesoft.faces处。 webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
    在com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
    。在com.icesoft.faces.webapp.http.servlet.PathDisp atcher.service(PathDispatcher.java:23)
    at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:53)
    at com.icesoft.faces.webapp。 http.servlet.SessionVerifier.service(SessionVerifier.java:26)
    位于com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
    位于com.icesoft。 faces.webapp.http.servlet.MainServlet.service(MainServlet.java:131)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at com.icesoft.faces。 webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:56)
    处org.apache.catalina.core org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    。 ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:343)
    at org.springframework.security.web.access。 intercept.FilterSecuri tyInterceptor.invoke(FilterSecurityInterceptor.java:109)
    位于org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    位于org.springframework.security.web。的FilterChainProxy $ VirtualFilterChain.doFilter处org.springframework.security.web org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
    (FilterChainProxy.java:355)
    。 FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    在org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
    在org.springframework.security.web。的FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    处org.springframework.security.web org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
    。的FilterChainProxy $ VirtualFilterCha in.doFilter(FilterChainProxy.java:355)
    在org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    。在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    在org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    。在org.springframework.security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    位于org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
    位于org.springframework.security.web。的FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    在org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
    在org.springframework.security .web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework .security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    在org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    在org.springframework .security.web.FilterChainProxy $ VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
    at org.springframework.web .filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    在org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    在org.apache.catalina.core.ApplicationFilterChain .internalDoFilter(ApplicationFilterChain.java:235)
    at或g.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache。 catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    处org.apache.catalina.valves org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    。 ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service( CoyoteAdapter.java:298)
    在org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    在org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol。 java:588)
    at org.apache.tomcat.util.net.JIoEndpoint $ Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)
    由:javax.persis引起tence.OptimisticLockException $在org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:1261)B
    $ b。在org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1187)
    。在org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
    处org.hibernate.ejb.criteria org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:250)
    。 CriteriaQueryCompiler $ 3.getResultList(CriteriaQueryCompiler.java:260)
    在edu.pitt.nmrl.med.services.SurveyService.checkMedicalDup(SurveyService.java:613)
    在edu.pitt.nmrl.med.services .SurveyService.save(SurveyService.java:790)
    at edu.pitt.nmrl.med.services.SurveyService $$ FastClassByCGLIB $$ b6424505.invoke(<生成>)
    at net.sf. cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    在org.springframework.aop.framework.Cglib2AopProxy $ CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy。 Java的:在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150 692)

    在org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    在org.springframework.aop.framework.Cglib2AopProxy $ DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
    $处b $ b


    解决方案

    以下是乐观锁定的工作原理:




    1. User1开始编辑recordA - recordA 版本 V

    2. User2开始编辑recordA - recordA 从数据库加载版本 V - 与上面完全相同

    3. User1保存了recordA - recordA Hibernate透明地添加:

      $ $ p $ code $ UPDATE

      SET V = V + 1
      WHERE version = V

      此时Hibernate会验证从数据库返回的已修改记录的数目是否准确的 1 即可。如果查询修改为0,则意味着未满足 WHERE version = V 子句。在这种情况下,一切都很顺利,版本设置为 V + 1 (重要!)


    4. User2保存了recordA - Hibernate完全一样,仍旧在内存中拥有旧的 V 版本号。不幸的是,在这种情况下,由于版本现在 V + 1 ,因此不符合 WHERE version = V 条件。查询返回0个修改的记录,这使得Hibernate相信(正确)记录在此期间被修改。这是例外情况。




    那么你能做些什么呢?简单地捕捉异常并且:重复整个事务,但重新加载实体(使用新版本 V + 1 ),以便在更新后不会丢失上次更改 或者通知用户对象已被修改在此期间她可以检查新版本。


这两种解决方案都取决于您的使用情况。 p>

I am using Hibernate 3.5.2 and Spring Core 3.0.1 in a Java J2EE Web Application. I am getting a StaleObjectStateExcpetion when separate users are updating the same record concurrently. The transactions are managed by javax.persistence.EntityManager. Here are the steps I take to create the issue.

  1. User1 logs into the application
  2. User2 logs into the application
  3. User1 starts to edit recordA
  4. User2 starts to edit recordA
  5. User1 saves recordA
  6. User2 saves recordA
  7. An org.hibernate.StaleObjectStateException is thrown (see below)

I have read that this is caused by a difference between the updated version number in the database and the version number currently in memory for that particular entity. However, when I try to find the current version number in the database using a query or by using the EntityManager.find() method to get the latest information from the database, I find no difference in the version numbers. I have also tried to merge changes between the old entity and the new entity both manually and using the entityManager.merge(object) method with no luck. Any ideas on how to fix this issue?

13290 [http-8080-7] ERROR org.hibernate.event.def.AbstractFlushingEventListener  - Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [edu.pitt.nmrl.med.domain.medical.MedicalHistory#362]
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1934)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2578)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2478)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2805)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:114)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:180)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
    at org.hibernate.event.def.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:64)
    at org.hibernate.impl.SessionImpl.autoFlushIfRequired(SessionImpl.java:1175)
    at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1251)
    at org.hibernate.impl.QueryImpl.list(QueryImpl.java:102)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:241)
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.getResultList(CriteriaQueryCompiler.java:260)
    at edu.pitt.nmrl.med.services.SurveyService.checkMedicalDup(SurveyService.java:613)
    at edu.pitt.nmrl.med.services.SurveyService.save(SurveyService.java:790)
    at edu.pitt.nmrl.med.services.SurveyService$$FastClassByCGLIB$$b6424505.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
    at edu.pitt.nmrl.med.services.SurveyService$$EnhancerByCGLIB$$5831613c.save(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:328)
    at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:273)
    at org.jboss.el.parser.AstMethodSuffix.getValue(AstMethodSuffix.java:59)
    at org.jboss.el.parser.AstMethodSuffix.invoke(AstMethodSuffix.java:65)
    at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
    at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
    at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:387)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:475)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:756)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:18)
    at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.renderCycle(ReceiveSendUpdates.java:132)
    at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.service(ReceiveSendUpdates.java:74)
    at com.icesoft.faces.webapp.http.core.RequestVerifier.service(RequestVerifier.java:31)
    at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
    at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
    at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
    at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:53)
    at com.icesoft.faces.webapp.http.servlet.SessionVerifier.service(SessionVerifier.java:26)
    at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
    at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:131)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at com.icesoft.faces.webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:56)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)
Jan 23, 2012 12:07:16 PM com.sun.faces.application.ActionListenerImpl processAction
SEVERE: javax.persistence.OptimisticLockException
javax.faces.el.EvaluationException: javax.persistence.OptimisticLockException
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
    at javax.faces.component.UICommand.broadcast(UICommand.java:387)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:475)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:756)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at com.icesoft.faces.webapp.http.core.JsfLifecycleExecutor.apply(JsfLifecycleExecutor.java:18)
    at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.renderCycle(ReceiveSendUpdates.java:132)
    at com.icesoft.faces.webapp.http.core.ReceiveSendUpdates.service(ReceiveSendUpdates.java:74)
    at com.icesoft.faces.webapp.http.core.RequestVerifier.service(RequestVerifier.java:31)
    at com.icesoft.faces.webapp.http.common.standard.PathDispatcherServer.service(PathDispatcherServer.java:24)
    at com.icesoft.faces.webapp.http.servlet.BasicAdaptingServlet.service(BasicAdaptingServlet.java:16)
    at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
    at com.icesoft.faces.webapp.http.servlet.SessionDispatcher.service(SessionDispatcher.java:53)
    at com.icesoft.faces.webapp.http.servlet.SessionVerifier.service(SessionVerifier.java:26)
    at com.icesoft.faces.webapp.http.servlet.PathDispatcher.service(PathDispatcher.java:23)
    at com.icesoft.faces.webapp.http.servlet.MainServlet.service(MainServlet.java:131)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at com.icesoft.faces.webapp.xmlhttp.BlockingServlet.service(BlockingServlet.java:56)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)
Caused by: javax.persistence.OptimisticLockException
    at org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:1261)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1187)
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1168)
    at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:250)
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.getResultList(CriteriaQueryCompiler.java:260)
    at edu.pitt.nmrl.med.services.SurveyService.checkMedicalDup(SurveyService.java:613)
    at edu.pitt.nmrl.med.services.SurveyService.save(SurveyService.java:790)
    at edu.pitt.nmrl.med.services.SurveyService$$FastClassByCGLIB$$b6424505.invoke(<generated>)
    at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
    at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625)
    at 

解决方案

Here is how optimistic locking works:

  1. User1 starts to edit recordA - recordA is loaded from the database with version V
  2. User2 starts to edit recordA - recordA is loaded from the database with version V - exactly the same as above
  3. User1 saves recordA - recordA is saved but Hibernate transparently adds:

    UPDATE
    ...
    SET V = V + 1
    WHERE version = V
    

    At this point Hibernate verifies whether the number of modified records returned from the database is exactly 1. If the query modified 0 records it means that the WHERE version = V clause was not met. In this case everything went fine and the version was set to V + 1 (important!)

  4. User2 saves recordA - Hibernate does exactly the same thing, still having the old V version number in memory. Unfortunately in this case the WHERE version = V condition is not met since version is now V + 1. The query returns 0 modified records which makes Hibernate believe (correctly) that the record was modified in the meantime. This is what the exception says.

So what can you do about it? Simply catch the exception and:

  1. Repeat the whole transaction, but reload the entity (with new version V + 1) so that after updating you won't loose the last change

  2. Or inform the user that the object was modified in the meantime so she can inspect the new version.

Both solutions are fine depending on your use case.

这篇关于并发更新期间的Hibernate StaleObjectStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆