我有旧版数据库,有些表有复合ID
class Client {
String id
static hasMany = [
settings: Setting
]
static mapping = {
id column: 'client_id', generator: 'assigned'
}
}
class Setting {
Client client
String nodeId
String ccyPairPattern
Character qualifier
static mapping = {
id composite: ['client', 'nodeId', 'pattern', 'qualifier']
}
}
我想从GORM关联中删除条目:
client.get('1').removeFromSettings(settingToRemove)
// settingToRemove.delete(flush: true)
// delete-orphans does not help
刷新后总是会引发异常
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) :
发生这种情况是因为方法removeFrom *将客户端属性设置为null,并生成要删除的查询,其中clientId = null,因为客户端是复合键的一部分
在这种情况下最好的解决方案是什么。看起来GORM对复合键的支持不佳,或者我的映射不正确。
最佳答案
当您使用hasMany在许多方面都没有belongsTo时,换句话说,是单向关联,就会得到一个联接表。例如...
class PurchaseOrder {
static hasMany = [items: Item]
}
class Item { }
将产生三个数据库表:purchase_order,item和purchase_order_items。 Purchase_order_items表将包含两列:purchase_order_id和item_id。您可以阅读有关联接表here的更多信息。
由于您正在处理旧数据库,因此我认为最好的解决方案是不使用
addTo*()
和removeFrom*()
。Setting
实例。 示例:
def client = Client.get(1)
// Adding a setting
def setting = new Setting(client: client, nodeId: blah...)
setting.save()
// Removing a setting
/*
The prototype is used to search for a domain instance with a composite primary key.
So simply set the composite key properties accordingly.
*/
def prototype = new Setting(client: client, nodeId: blah...)
def setting = Setting.get(prototype)
setting.delete()
缺少hasMany关联,您将无法通过
client.settings
属性访问客户端的设置。相反,您必须像这样查询它们:def settings = Setting.findByClient(client)
使用遗留数据库的结果是,如果数据库与该GORM / Hibernate期望的不一致,那么它将为您提供的服务受到限制。
关于grails - 关联中的GORM和复合键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32846904/