Grails:尝试使用嵌套对象保存对象。没有错误但没有ID

时间:2015-03-23 19:02:50

标签: grails gorm

这是我的应用程序:我的用户是由三个elemtents

组成的
  1. 用户(用户名,密码,角色等。来自SpringSecurity)
  2. AppUser (姓氏等基本详情)
  3. 详细信息用户(具体应用详情。工作区域等)
  4. AppUser包含User和DetailUser的实例(此lastone nullable)

    这是我的代码:

     if (user.validate() &&  appUser.validate() ){
                user.save()
                appUser.user = user
                appUser.save()
    
                appUserDetail.appUser = appUser
                appUserDetail.save()
    
            }
    

    没有错误验证,但我的appUser的ID为空!

    真诚地,我不明白为什么。

    更新

    Hibernate.AssertionFailure an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
    org.hibernate.AssertionFailure: null id in it.geny.auth.AppUser entry (don't flush the Session after an exception occurs)
    

2 个答案:

答案 0 :(得分:1)

首先,如果没有.save(),您failOnError: true就不会收到任何错误 即

user.save(failOnError: true)

它只是静静地不保存而不是真的通知它失败了(如果你想看到失败,你必须检查它是否包含错误)。

最后,在有关正在创建连接表的保存的大量事件中会出现该特定错误。

我见过的最好的是你要确保父母和孩子都有相互联系的链接。所以,你想做这样的事情:

 if (user.validate() &&  appUser.validate() ){
        user.appUser = appUser
        appUser.user = user
        appUserDetail.appUser = appUser
        appUser.UserDetail = appUserDetail

        appUserDetail.save(failOnError: true)
        appUser.save(failOnError: true)
        user.save(failOnError: true)

    }

我没有测试这段代码,你可能不得不稍微调整一下,但关键是你要确保每个对象在保存之前都指向另一个。

可能没有必要使用failOnError,并且您可能不希望在保存失败的情况下抛出异常,在这种情况下,您只需调用.save()然后检查user.errors给出错误。通常我会在gsp中使用g:eachError标记向最终用户显示错误,以便他们清理提交内容并重试。

答案 1 :(得分:0)

最后我找到了解决方案。

在SO上搜索有关此问题的帖子,我发现了很多关于此事的帖子。有人说:

<Domain>.get(id)

可能会关闭会话,因此不会保存对象。 但是我在哪里调用.get函数?!?!?

下面:

def appUser = new AppUser(params)

在里面,我与许多domanins(例如地区)有一对一的关系。在 GrailsParameterMap 中,我有 params。&#34; appUser.region&#34; ,其中包含Region的ID。

如果我使用grails的绑定器(spring)(我无法检查代码,但如果这是真的,我会在某处找到.get(id)...),我的对象将不会持久化。

但是,如果我手动绑定,一切正常,我的对象就会被保存。