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

答えは次のとおりです。

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 に答える
0

試してみてください:

person1.removeFromRoles(role) //role は、人物を削除するロール オブジェクトです
role.person = person2 動作する必要があり

ます。

于 2012-08-15T09:34:36.187 に答える