无法在grails中实现软删除

时间:2015-03-18 07:17:23

标签: grails gorm soft-delete

我正在尝试找到适当的方法来实现我的实体数量的软删除。 我到目前为止找到的最好的方法是使用beforeDelete()回调。

所以我的班级看起来像这样:

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
    }
}

我的案例中的删除是通过事务服务类执行的,如下所示:

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,则没有错误,但没有任何更新。

1 个答案:

答案 0 :(得分:1)

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

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

    return false
}

我试图绕过类似的问题一次,问题是,当你确实更新你的方式时,它不会立即完成,但它会进入休眠的会话并且它会持续存在于同一时间访问对象时可能会出现异常。 Hql直接保存它