gpt4 book ai didi

hibernate - Grails Controller 无论如何都会保存域项目

转载 作者:行者123 更新时间:2023-12-02 14:24:00 25 4
gpt4 key购买 nike

使用 Grails 2.3.9

在 Controller 中,我做了一些检查,当失败时返回自定义错误响应。这是一个代码片段:

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 session 断开连接。我将如何在 Grails 中执行此操作?

更新:在域实例搭建的 Controller 中, 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(),而是使用事务和数据库的 native 事务特性。我建议将逻辑移动到服务中(将 Controller 流代码和应用程​​序的逻辑分开。例如:

class GroupService {
@Transactional
void updateBook(params) {
....
// do custom checks
if(checksFailed) {
status.setRollbackOnly() // rollback transaction
}
else {
instance.save flush:true
}
}
}

您可以调用 setRollbackOnly关于事务状态或抛出运行时异常。

请注意,如果您使用异常,它们可能会很昂贵,因此最好创建自定义异常类型,例如 GroupUpdateException并覆盖 fillInStackTrace不填充堆栈跟踪,从而降低异常成本。见 Why is Throwable.fillInStackTrace() method public? Why would someone use it?

关于hibernate - Grails Controller 无论如何都会保存域项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24138556/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com