0

我有一个遗留数据库,我正在使用 Grails。错误#1。

它使用复合键。错误 #2。

给定这些域类:

Movie {
    static hasMany = [ roles: Role ]
}
Person {
    static hasMany = [ roles: Role ]
}
Role {
    Movie movie
    Person person
    String foo
}

我想将角色从一个人转移到另一个人,如下所示:

Role x = person1.roles[0]
x.person = person2
save(flush:true)

但什么也没有发生。完全没有。我在 log4j 中为休眠打开了跟踪和调试级别日志记录,它没有显示更新语句。但是,如果我这样做:

Role x = person1.roles[0]
x.person = person2
x.foo = "i can haz update?"
save(flush:true)

foo 确实发生了更新,但指向 person 的外键没有被修改,如下所示:

DEBUG hibernate.SQL  - update ct_roles set foo=? where movie_id=? and person_id=?
TRACE sql.BasicBinder  - binding parameter [1] as 'i can haz update?'
TRACE sql.BasicBinder  - binding parameter [2] as [BIGINT] - 999
TRACE sql.BasicBinder  - binding parameter [3] as [BIGINT] - 2

请注意,person_id 2 属于 person2,目前还没有角色,因此更新失败。

那么,除了简单地删除旧角色并创建一个附加到所需人员的新角色之外,有没有办法解决这个问题?

4

2 回答 2

0

尝试:

person1.removeFromRoles(role) //role 是要从中删除人员的角色对象
role.person = person2

应该可以工作。

于 2012-08-15T09:34:36.187 回答
0

答案是:

class Role { 
    Movie movie
    Person person
    String fuGorm

    def move(Person newbie) {
        def m = this.movie?.id
        def p = this.person?.id
        def n = newbie?.id

        // bypass GORM and issue a raw SQL update command...
        def q = "update ct_roles set person_id=$n where person_id=$p and movie_id=$m"
        def success = runCommand(q)

        if (success) {
            // the above bypasses GORM, so we should still
            // perform the operation using GORM speak
            // otherwise our objects will be out of sync with the DB.
            // The following EPIC FAILS to update the DB, 
            // but it does update the local Grails domain objects
            this.person.removeFromRoles(this)
            this.person = newbie
            newbie.addToRoles(this)
        }
        return success
    }
    def runCommand = { query ->
        def db = new Sql(dataSource)
        db.execute (query)
    }
}
于 2012-08-15T22:28:18.553 回答