我试图在我的控制器update
方法中调用一些服务。不幸的是,这导致StaleObjectStateException
,我真的不知道为什么,因为我只是"只是"调用transactional
以下是例外:
| Error 2015-06-21 15:43:43,091 [http-bio-8080-exec-7] ERROR errors.GrailsExceptionResolver - StaleObjectStateException occurred when processing request: [PUT] /time-tracking-backend/projectBooking/update/1 - parameters:
date: struct
duration: 120
date_year: 2015
date_month: 6
project.id: 1
_method: PUT
_action_update: Aktualisieren
comment: jojo
date_day: 21
version: 0
subProject.id: 2
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [projectmanagement.SubProject#2]. Stacktrace follows:
Message: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [projectmanagement.SubProject#2]
Line | Method
->> 48 | $tt__setActualHours in projectmanagement.ProjectService$$EPGFZqxM
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 201 | $tt__update in timemanagement.ProjectBookingController$$EPGFYoBE
| 198 | doFilter . . . . . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 53 | doFilter . . . . . in grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter
| 139 | doFilter in grails.plugin.springsecurity.rest.RestAuthenticationFilter
| 49 | doFilter . . . . . in grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter
| 82 | doFilter in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
| 80 | doFilter . . . . . in grails.plugin.springsecurity.rest.RestLogoutFilter
| 82 | doFilter in com.brandseye.cors.CorsFilter
| 1142 | runWorker . . . . . in java.util.concurrent.ThreadPoolExecutor
| 617 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . . . . . . in java.lang.Thread
......
..和我的控制器更新方法中的重要部分:
if(projectBookingInstance.getPersistentValue("subProject") != projectBookingInstance.subProject
|| projectBookingInstance.getPersistentValue("date") != projectBookingInstance.date){
ProjectBooking projectBookingToBeUpdated = ProjectBooking.get(projectBookingInstance.id)
if(projectBookingToBeUpdated != null){
projectService.deleteActualHours(projectBookingToBeUpdated)
projectBookingToBeUpdated.delete(flush:true)
projectService.setActualHours(projectBookingToBeUpdated)
projectBookingInstance.save(flush:true)
return
}
}
两种服务方式:
def deleteActualHours(ProjectBooking projectBookingInstance){
Project project = projectBookingInstance.project
SubProject subProject = projectBookingInstance.subProject
Double duration = projectBookingInstance.duration / 60
duration = duration.round(2)
project.actualHours -= duration
subProject.actualHours -= duration
project.save(flush:true)
subProject.save(flush:true)
}
def setActualHours(ProjectBooking projectBookingInstance){
Project project = projectBookingInstance.project
SubProject subProject = projectBookingInstance.subProject
Double duration = (projectBookingInstance.duration/60)
duration = duration.round(2)
project.actualHours += duration
subProject.actualHours += duration
project.save(flush:true)
subProject.save(flush:true)
}