views:

30

answers:

1

i have a method inside service layer that is called by view layer to save content. the model is annotated with @Version JPA so support concurrent-update. but during web application peak-usage, sometime, i will get

17 Aug 2010 16:30:26,477 ERROR [http-2020-23] - Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.company.iss.model.IssAnswer#58840]
    at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1759)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2402)
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2302)
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2602)
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:96)
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1001)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:339)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:655)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:732)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:321)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:116)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
    at $Proxy56.storeAnswerFromForm(Unknown Source)
    at com.company.iss.pages.RateYourServiceSupplierFromYourOwnDIVBUStep2.saveAndNext(RateYourServiceSupplierFromYourOwnDIVBUStep2.java:241)
    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.apache.tapestry.listener.ListenerMethodInvokerImpl.invokeTargetMethod(ListenerMethodInvokerImpl.java:276)
    at org.apache.tapestry.listener.ListenerMethodInvokerImpl.invokeListenerMethod(ListenerMethodInvokerImpl.java:221)
    at org.apache.tapestry.listener.ListenerMethodInvokerImpl.searchAndInvoke(ListenerMethodInvokerImpl.java:157)
    at org.apache.tapestry.listener.ListenerMethodInvokerImpl.invokeListenerMethod(ListenerMethodInvokerImpl.java:80)
    at org.apache.tapestry.listener.SyntheticListener.actionTriggered(SyntheticListener.java:52)
    at org.apache.tapestry.binding.ListenerMethodBinding.actionTriggered(ListenerMethodBinding.java:77)
    at org.apache.tapestry.listener.ListenerInvokerTerminator.invokeListener(ListenerInvokerTerminator.java:50)
    at $ListenerInvoker_12a7f1445cd.invokeListener($ListenerInvoker_12a7f1445cd.java)
    at org.apache.tapestry.form.AbstractSubmit.handleClick(AbstractSubmit.java:98)
    at org.apache.tapestry.form.AbstractSubmit.rewindFormComponent(AbstractSubmit.java:63)
    at org.apache.tapestry.form.AbstractFormComponent.renderComponent(AbstractFormComponent.java:90)
    at org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:724)
    at org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:187)
    at org.apache.tapestry.AbstractComponent.renderBody(AbstractComponent.java:538)
    at org.apache.tapestry.components.IfBean.renderComponent(IfBean.java:94)
    at org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:724)
    at org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:187)
    at org.apache.tapestry.AbstractComponent.renderBody(AbstractComponent.java:538)
    at org.apache.tapestry.components.IfBean.renderComponent(IfBean.java:94)
    at org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:724)
    at org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:187)
    at org.apache.tapestry.AbstractComponent.renderBody(AbstractComponent.java:538)
    at org.apache.tapestry.form.FormSupportImpl.rewind(FormSupportImpl.java:624)
    at org.apache.tapestry.form.Form.renderComponent(Form.java:196)
    at org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:724)
    at org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:187)
    at org.apache.tapestry.form.Form.rewind(Form.java:269)
    at org.apache.tapestry.engine.RequestCycle.rewindForm(RequestCycle.java:469)
    at org.apache.tapestry.form.Form.trigger(Form.java:280)
    at org.apache.tapestry.engine.DirectService.triggerComponent(DirectService.java:166)
    at org.apache.tapestry.engine.DirectService.service(DirectService.java:142)
    at $IEngineService_12a7f144648.service($IEngineService_12a7f144648.java)
    at org.apache.tapestry.services.impl.EngineServiceOuterProxy.service(EngineServiceOuterProxy.java:72)
    at org.apache.tapestry.engine.AbstractEngine.service(AbstractEngine.java:241)
    at org.apache.tapestry.services.impl.InvokeEngineTerminator.service(InvokeEngineTerminator.java:54)
    at $WebRequestServicer_12a7f14461f.service($WebRequestServicer_12a7f14461f.java)
    at $WebRequestServicer_12a7f14461b.service($WebRequestServicer_12a7f14461b.java)
    at org.apache.tapestry.services.impl.WebRequestServicerPipelineBridge.service(WebRequestServicerPipelineBridge.java:61)
    at $ServletRequestServicer_12a7f144601.service($ServletRequestServicer_12a7f144601.java)
    at org.apache.tapestry.request.DecodedRequestInjector.service(DecodedRequestInjector.java:55)
    at $ServletRequestServicerFilter_12a7f1445fd.service($ServletRequestServicerFilter_12a7f1445fd.java)
    at $ServletRequestServicer_12a7f144603.service($ServletRequestServicer_12a7f144603.java)
    at org.apache.tapestry.multipart.MultipartDecoderFilter.service(MultipartDecoderFilter.java:52)
    at $ServletRequestServicerFilter_12a7f1445fb.service($ServletRequestServicerFilter_12a7f1445fb.java)
    at $ServletRequestServicer_12a7f144603.service($ServletRequestServicer_12a7f144603.java)
    at org.apache.tapestry.services.impl.SetupRequestEncoding.service(SetupRequestEncoding.java:53)
    at $ServletRequestServicerFilter_12a7f1445ff.service($ServletRequestServicerFilter_12a7f1445ff.java)
    at $ServletRequestServicer_12a7f144603.service($ServletRequestServicer_12a7f144603.java)
    at $ServletRequestServicer_12a7f1445f5.service($ServletRequestServicer_12a7f1445f5.java)
    at org.apache.tapestry.ApplicationServlet.doService(ApplicationServlet.java:126)
    at org.apache.tapestry.ApplicationServlet.doPost(ApplicationServlet.java:171)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378)
    at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
    at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    at org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    at org.springframework.security.ui.ntlm.NtlmProcessingFilter.doFilterHttp(NtlmProcessingFilter.java:351)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    at org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilterHttp(RememberMeProcessingFilter.java:116)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:277)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
    at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
    at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
    at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
    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:128)
    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:286)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:619)

1.I suspect user click "save" on view layer more than 1 times.. do you agreed?
2. do you think i should put synchronized for my save method in service layer?
3. should i use UI-javascript to block submit 'save' twice in view layer

+1  A: 
  1. If no other users were updating the entity at the same time - yes.
  2. It wouldn't help. Updates are already synchronized by transactions, so this exception is caused by consequent updates with the same version value.
  3. It's a good practise for better user experience regardless the underlying problems.
axtavt