我有一个遗留数据库,我正在使用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中打开了hibernate的跟踪和调试级别日志记录,它没有显示更新语句。但是,如果我这样做:
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,目前尚无角色,因此更新失败。
因此,如果没有简单地删除旧角色并创建一个附加到所需人员的新角色,有没有办法解决这个问题?
答案 0 :(得分:0)
尝试:
person1.removeFromRoles(role) // role是要从中删除人员的角色对象
role.person = person2
应该工作。
答案 1 :(得分: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)
}
}