无法在 grails 中实现软删除

Trouble implementing soft delete in grails

我正在尝试找到对我的多个实体实施软删除的正确方法。 到目前为止我发现的最好方法是使用 beforeDelete() 回调。

所以我的 class 看起来像这样:

class Goal {

    String definition;
    Account account;
    boolean tmpl = false;
    String tmplName;

    Timestamp dateCreated
    Timestamp lastUpdated
    Timestamp deletedAt
    ...
    def beforeDelete() {
        if (deletedAt == null) {
            deletedAt = new Timestamp(System.currentTimeMillis())
            this.save()
        }

        return false
    }
}

我的删除是通过事务服务class执行的,如下:

def deleteTemplate(Goal tmpl) {
    if (tmpl.tmpl != true) {
        throw new ValidationException("Provided object is not template!")
    }

    //delete related perceptions
    for (perception in tmpl.perceptions) {
        perception.delete()
    }

    tmpl.delete()
}

我得到的只是一个错误:

    Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [triz.rrm.Perception#3]. Stacktrace follows:
Message: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [triz.rrm.Perception#3]
    Line | Method
->>   63 | beforeDelete       in triz.rrm.Goal
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    153 | call               in org.grails.datastore.gorm.support.EventTriggerCaller$MethodCaller
|     96 | call . . . . . . . in org.grails.datastore.gorm.support.EventTriggerCaller
|     47 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
|    138 | deleteTmpl . . . . in triz.rrm.RrmTemplateController
|    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
|     49 | doFilter . . . . . in grails.plugin.springsecurity.web.authentication.RequestHolderAuthenticationFilter
|     82 | doFilter           in grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter
|   1142 | runWorker . . . .  in java.util.concurrent.ThreadPoolExecutor
|    617 | run                in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run . . . . . . .  in java.lang.Thread

我已经尝试了所有方法,包括用新会话和新事务包装它,但没有任何帮助。我错过了什么?

感谢您的建议。 亚历克斯

P.S。如果我将服务标记为 NotTransactional,没有错误,但没有任何更新。

我不知道这是否有帮助,但也许您可以尝试在 beforeDelete() 中使用 hql:

def beforeDelete() {
    if (deletedAt == null) {
        Goal.executeUpdate('update Goal set deletedAt = ? where id = ?', [new Timestamp(System.currentTimeMillis()), id])
    }

    return false
}

我曾经试图解决类似的问题,问题是当你更新你的方式时,它不会立即完成,但它会进入休眠会话并且在刷新时持续存在访问对象时可能会出现此类异常。 hql直接保存