我有两个以下域名:
User {
UserData userData
}
UserData {
static belongsTo = [user: User]
}
并且在某些时候我想将两个用户合并为一个。我的意思是删除一个User实例并将userData附加到另一个用户。
我试过了:
User zombieUser
User liveUser
UserData data = zombieUser.userData
zombieUser.delete()
liveUser.userData = data
userData.user = liveUser
userData.save()
liveUser.save()
其实我尝试了不同的变种,不同的顺序,似乎所有可能的方式。但它总是失败,但有例外。当前代码将失败:
deleted object would be re-saved by cascade (remove deleted object from associations): [UserData#1]
如果我在zombie.delete()
之后将*.save()
置于最低点,我会得到:
Field error in object 'User' on field 'userData': rejected value [UserData : 1]; codes ... default message [Property [{0}] of class [{1}] with value [{2}] must be unique]
有没有办法将现有对象从一个对象重新连接到另一个对象?
工作代码:
UserData userData = zombieUser.userData
userData.user = null
zombieUser.userData = null
zombieUser.save(flush: true)
userData.save()
liveUser.userData = userData
userData.user = liveUser
liveUser.save()
userDate.save(flush: true)
答案 0 :(得分:1)
问题在于,由于您的belongsTo
声明,并且根据cascading rules,只要删除了userData
,就会从数据库中删除zombieUser
。调用liveUser.save()
后,userData
将再次保存。顺便说一下,您再次不需要致电userData.save()
,因为此belongsTo
声明,liveUser.save()
会级联到userData
。
我看到两个选项来解决您的问题:
对新的userData
对象执行深UserData
的副本,并将此对象附加到liveUser
,如下所示:
withTransaction {
UserData data = new UserData(prop: zombieUser.userData.prop)
liveUser.userData = data
zombiUser.delete()
liveUser.save()
}
删除zombieUser
时,将通过级联删除旧的UserData对象,并在保存liveUser
时创建一个新的。
从belongsTo
移除userData
。您将不再受益于级联,并且必须自行管理保存userData
,并制作如果没有user.userData
引用它,请确保从数据库中删除user
(不要忘记为此进行交易,如同您多次调用save
或delete
时一样在你的方法中。)
您选择哪种方法取决于您的对象的耦合程度。通常情况下,如果它们非常耦合,您将受益于级联(通过belongsTo
)并且可能会为1.如果它们不是非常耦合(即可能有多个用户具有相同的userData),那么{{ 1}}错了,你应该选择方法2.
如果您的GORM模型具有复杂的依赖关系,GORM gotchas中提供的概念将极大地帮助您。
答案 1 :(得分:0)
您需要向域类添加映射,以告诉它在删除对象时要执行的操作。例如,删除父项也应删除其所有子项??
static mapping = {
userData cascade: "all-delete-orphan"
}