【问题标题】:Grails GORM rarely works in domain classesGrails GORM 很少在域类中工作
【发布时间】:2012-10-07 21:28:38
【问题描述】:

我在用户和组织之间有多对多的关系。当用户被删除时,我想从他的所有组织中删除用户,所以这基本上是我想出的:

class User {
    ...

    def beforeDelete() {
        def user = User.get(id)
        Organization.all.each {
            it.removeFromMembers(user)
            it.save()
        }
    }
}

这令人惊讶地不起作用,因为User.get(id) 返回 null 即使具有给定 id 的用户在数据库中,当我查看日志时,甚至没有执行任何 sql 语句。 所以我尝试使用load() insted 方法。 ObjectNotFoundException 就是结果。所以我尝试了这个,因为我很绝望:

def user = User.find("from User as u where u.id = ?", [1L])

出于某种原因,这可行。但是现在,it.removeFromMembers(user) 的行会抛出 NullPointerException。

我尝试将这个逻辑放在我的 UserController 中并且它有效!

这是为什么?为什么我不能在域类中这样做?这使得 beforeDelete 钩子(以及所有其他钩子)变得毫无用处。

【问题讨论】:

    标签: hibernate grails


    【解决方案1】:

    好吧,首先请务必阅读有关删除事件的documentation。您可以看到,要使任何更改实际反映在数据库中,您需要一个新会话,并且由于在事件内部您已经在处理要删除的当前对象,因此您不需要调用 get() 方法:

    def beforeDelete() {
      User.withNewSession {
         organizations.each{ org -> 
            org.removeFromMembers(this)
         }
         this.save()
      }
    }
    

    (以上代码未测试)

    get() 方法中有 null 的原因是因为触发事件时 id 不存在。如果要访问 id,则必须从当前对象中检索它:this.id

    【讨论】:

    • 感谢您的评论,但它不起作用。它抛出此消息的异常:具有相同标识符值的不同对象已与会话相关联:[com.redhat.theses.auth.User#1];嵌套异常是 org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话关联:[com.redhat.theses.auth.User#1]
    • 也许您需要在save() 之前调用this.merge(),正如我的回答中所述,代码尚未经过测试,只是一个参考,让您知道可以在域 =)
    • 是的,我明白了。至于 this.save() 之前的 this.merge() 也不起作用,同样的异常 :(
    猜你喜欢
    • 2010-12-22
    • 1970-01-01
    • 2011-09-14
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 2010-12-17
    相关资源
    最近更新 更多