Opt-out error in Grails GORM

I have a controller action in which I update a simple value in a domain object:

user = User.get(session.user.id) 
user.credits +=20 

Everything works fine until I use ajax. But in my application, I have to use ajax to pre-extract the content and save it in a javascript variable in the client. This ajax is initiated in the client without user interaction to pre-extract the content. This ajax request invokes exactly the same action and the same controller in which user.credits is changed. In this action, no other updates are made to the user. Other data about this domain object is read. The ajax request is asynchronous, therefore, when the request is executed for the same action, another request to the same action of the same client is very quickly executed. This triggers an upbeat demonstration of failures in Grails.

I tried all combinations of user.lock () user.save (flush: true)

before, during and / or after the update, but it does not matter.

If I do not use ajax-initiated requests, then the built-in functions for automatically saving grails objects, if they are dirty when exiting the controller action, work very well, and I do not even need to use user.save or user.lock ().

Is it a grail error or is something else missing? Has anyone experienced?

This is the stack trace:

ERROR events.PatchedDefaultFlushEventListener  - Could not synchronize database state with session 
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [zen37.User#8]
        at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1792) 
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2435) 
        at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335) 
        at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635) 
        at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115) 
        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.codehaus.groovy.grails.orm.hibernate.events.PatchedDefaultFlushEventListener.performExecutions(PatchedDefaultFlushEventListener.java:46) 
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) 
        at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:390) 
        at org.codehaus.groovy.grails.orm.hibernate.support.GrailsOpenSessionInViewInterceptor.flushIfNecessary(GrailsOpenSessionInViewInterceptor.java:120) 
        at org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor.postHandle(OpenSessionInViewInterceptor.java:181) 
        at org.codehaus.groovy.grails.orm.hibernate.support.GrailsOpenSessionInViewInterceptor.postHandle(GrailsOpenSessionInViewInterceptor.java:70)
        at org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter.postHandle(WebRequestHandlerInterceptorAdapter.java:61) 
        at org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet.doDispatch(GrailsDispatcherServlet.java:303) 
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) 
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) 
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) 
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70) 
        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.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646) 
        at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436) 
        at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374) 
        at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302) 
        at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:293) 
        at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:260) 
        at org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:251) 
        at org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter.doFilterInternal(UrlMappingsFilter.java:183) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.obtainContent(GrailsPageFilter.java:246) 
        at org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.doFilter(GrailsPageFilter.java:135) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.codehaus.groovy.grails.web.servlet.filter.GrailsReloadServletFilter.doFilterInternal(GrailsReloadServletFilter.java:104) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:69) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:65) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) 
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) 
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
        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: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:293) 
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849) 
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) 
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454) 
        at java.lang.Thread.run(Thread.java:619) 
2010-12-05 13:40:52,848 [http-8181-5] ERROR errors.GrailsExceptionResolver  - Object of class [zen37.User] with identifier [8]: optimistic locking failed; nested exception is org.hibernate.StaleObject 
StateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [zen37.User#8] 
org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Object of class [zen37.User] with identifier [8]: optimistic locking failed; nested exception is org.hibernate.StaleObjec 
tStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [zen37.User#8] 
        at java.lang.Thread.run(Thread.java:619) 
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [zen37.User#8] 
        ... 1 more
+3
source share
4 answers

If you are saving an instance of a custom domain object in your session, you need to use merging instead of saving. See http://www.grails.org/doc/latest/ref/Domain%20Classes/merge.html

+4
source

Try using something like this:

if(!user.isAttached()){
    user.attach()
}

, (, ).

+1

vs get

User.read(session.user.id)

.

0

, cookie GUI, ( , ). - SQL ( ). , . .

. , .

In your case, I think you need to insert something into the "credits" table attached to the user. Do not do this with user.addToCredits (). Save (), because it will change the user, do it with the help of a new loan (user: user) .save (), because it does not change the user - do not ask me why ;-) Then, to get the user's credit, you can count the contents of user credits with something like user.credits.size ()

0
source

Source: https://habr.com/ru/post/1778848/


All Articles