当验证失败时我得到(发生异常后不刷新会话)错误消息,为啥?

Posted

技术标签:

【中文标题】当验证失败时我得到(发生异常后不刷新会话)错误消息,为啥?【英文标题】:When The Validation Fails I Get (don't flush the Session after an exception occurs) Error Message, Why?当验证失败时我得到(发生异常后不刷新会话)错误消息,为什么? 【发布时间】:2012-03-27 22:36:53 【问题描述】:

我有一个名为Project 的域类:

class Project  
        static hasMany = [ tasks : Tasks , users : User ] 
        static belongsTo = User 
        String name 
        static constraints =  
                name(nullable:false,unique:true, size:5..20) 
                tasks(nullable:true) 
                users(nullable:true) 
         
        String toString()  
                this.name 
         
 

我使用以下代码保存Project 实例:

def save()  
        def user = User.get(springSecurityService.principal.id) 
        def projectInstance = new Project(params) 
        projectInstance.addToUsers(user) 
        if (!projectInstance.save(flush: true))  
            render(view: "create", model: [projectInstance: projectInstance]) 
            return 
         
      flash.message = message(code: 'default.created.message', args: [message(code: 'project.label', default: 'Project'), projectInstance.id]) 
        redirect(action: "showCreatedProject", id: projectInstance.id) 
     

如果我给出Project name,上面的代码可以正常工作,它通过了域类验证。但是,如果我将fail 之类的东西作为Project name (未通过域类验证)我会收到这样的错误:

Message: null id in mnm.schedule.Project entry (don't flush the Session after an exception occurs) 
Trace:   Line | Method 
->> 886 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   908 | run     in     '' 
^   662 | run . . in java.lang.Thread 

我对 Grails 很陌生,我不知道为什么会出现这个错误。我怎样才能摆脱这个错误?

提前致谢。

【问题讨论】:

如果你去掉了显式的flush调用,你还会得到异常吗?所以 save() 而不是 save(flush:true) ? @Gregg :是的,我已经尝试过了,它会导致同样的错误。但我发现问题出在projectInstance.addToUsers(user) 这一行。当我注释掉这一行时,一切正常。但我不知道如何保留那条线并仍然摆脱该错误! addToUsers() 需要已经保存的对象,似乎需要为该对象填充 ID 才能建立关系。你能尝试在.save()之后调用这个方法吗? @IgorArtamonov:你的权利。那是错误。为什么你不能把它作为答案,我会接受它;)? 这只是一个想法,因为我从未尝试过在save 之前创建addTo :) 我已将其添加为答案 【参考方案1】:

addToUsers() 需要已经保存的对象,因为它需要填充 ID 来建立关系。你应该在.save()之后调用这个方法

【讨论】:

虽然我很高兴这解决了您的问题,但我不确定答案是否 100% 准确。我的代码采用未保存的对象并添加其他未保存的对象,然后 hibernate 负责以正确的方式将其持久化。我认为在您的情况下,问题特别是因为您将持久对象添加到非持久对象的集合中。 似乎 grails 在添加之前也尝试保存它,但验证失败,所以他目前没有有效的 id addTo* 保存作为参数传递的关联,因为如果您使用“static belongsTo ...”,则以这种方式设置级联,文档的第一行明确说明:grails.org/doc/latest/ref/Domain%20Classes/belongsTo.html跨度>

以上是关于当验证失败时我得到(发生异常后不刷新会话)错误消息,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

我一直在尝试将数据从 Firestore 检索到 Flutter 的 Future builder 但在第一次构建时我收到错误消息我在刷新后得到数据

Android Studio 显示密码验证失败错误

部署.war文件时会出现glassfish异常

org.hibernate.AssertionFailure: [...] 条目中的空 id(发生异常后不要刷新会话)

Token验证失败是怎么回事

Firebase UI 身份验证登录错误 api 异常