Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate Grails控制器以任何方式保存域项_Hibernate_Grails_Grails Controller - Fatal编程技术网

Hibernate Grails控制器以任何方式保存域项

Hibernate Grails控制器以任何方式保存域项,hibernate,grails,grails-controller,Hibernate,Grails,Grails Controller,使用Grails2.3.9 在控制器中,我执行一些检查,当失败时返回自定义错误响应。以下是一段代码片段: def update() { def instance = Group.get(params.groupId) instance.properies = params if (instance.hasErrors()) { // going through here: instance is not saved respond ins

使用Grails2.3.9

在控制器中,我执行一些检查,当失败时返回自定义错误响应。以下是一段代码片段:

def update() {
    def instance = Group.get(params.groupId)
    instance.properies = params

    if (instance.hasErrors()) {
        // going through here: instance is not saved
        respond instance.errors, view:'edit'
        return
    }

    // do custom checks
    if(checksFailed) {
        // instance is saved anyways :(
        instance.discard()
        response.sendError(response.SC_CONFLICT)
        return
    }

    instance.save flush:true
    // ... respond success
}
当检查失败时,我的错误响应将按我的要求返回。但是,无论如何都会保存实例(未到达
instance.save
)。如何使Grails/Hibernate知道不保存此实例

另一种方法可能是断开实例与Hibernate会话的连接。在Grails中,我该怎么做

更新:在域实例搭建的控制器中,
instance.discard()
技巧可以工作:

def update(Group groupInstance) {
    if (groupInstance.hasErrors()) {
        // going through here: instance is not saved
        respond instance.errors, view:'edit'
        return
    }

    // do custom checks
    if(checksFailed) {
        // instance is not saved
        groupInstance.discard()
        response.sendError(response.SC_CONFLICT)
        return
    }

    groupInstance.save flush:true
    // ... respond success
}

我发现很难理解为什么它在一种情况下有效而在另一种情况下无效。

最好的方法不是使用discard(),而是使用事务和数据库的本机事务功能。我建议将逻辑移动到服务中(分离控制器流代码和应用程序的逻辑)。示例:

class GroupService {
   @Transactional
   void updateBook(params) {
       ....
       // do custom checks
       if(checksFailed) {
          status.setRollbackOnly() // rollback transaction        
       }
       else {
           instance.save flush:true
       }
   }
}
您可以对事务状态调用
setRollbackOnly
,也可以引发运行时异常


注意:如果使用异常,它们可能会很昂贵,因此最好创建一个自定义异常类型,例如
GroupUpdateException
,并覆盖
fillInStackTrace
,以不填充堆栈跟踪,从而降低异常的成本。请参阅我倾向于接受您的第二个建议(使用异常)。但是,问题中的案例不起作用有什么原因吗?我想,这就是解决问题的方法。感谢您的回答。可能是您的附加检查执行的查询导致更新自动刷新,因此查询是一致的,这就是为什么使用事务很重要