我在尝试持久化两个实体之间的关联时遇到了一个奇怪的问题。当我使用Set
(即Grails的默认值)时,它可以工作,但是如果我尝试使用List
,子表中的关联在我的域类中设置它和生成的SQL插入语句之间的某个地方丢失。
我已经从我的应用程序中提取了有问题的代码,并设置了最简单的测试用例来显示问题-它涉及下面所示的3个域对象。
class Client {
String name
List<ModelFieldInstance> clientModelFieldInstances
static hasMany = [clientModelFieldInstances: ModelFieldInstance]
}
class ModelFieldDefinition {
String name
static hasMany = [ modelFieldInstances: ModelFieldInstance ]
def afterInsert() {
Client.findAll().each { client ->
ModelFieldInstance.withNewSession {
ModelFieldInstance modelFieldInstance = new ModelFieldInstance(['modelFieldDefinition.id': this.id, 'client.id': client.id])
modelFieldInstance.save()
}
}
}
}
class ModelFieldInstance {
String value
static belongsTo = [ modelFieldDefinition: ModelFieldDefinition, client: Client ]
}
在引导。groovy,我正在创建一个客户端和一个ModelFieldDefinition -
Client client = new Client(name: 'Some Client')
client.save(flush: true)
ModelFieldDefinition contactName = new ModelFieldDefinition([name: 'Contact Name'])
contactName.save(flush: true)
ModelFieldDefinition中的afterInsert方法用于为每个客户端创建空的ModelFieldInstances。如果我使用STS调试器逐步执行afterInsert代码,我可以看到modelFieldInstance。客户端有正确的值,但是一旦modelFieldInstance.save()
被调用,我得到一个异常说,modelFieldInstance。客户端为空-
Caused by MySQLIntegrityConstraintViolationException: Column 'client_id' cannot be null
如果我改变我的Client
类,删除List
声明,像这样-
class Client {
String name
static hasMany = [clientModelFieldInstances: ModelFieldInstance]
}
则正确地持久化关联。为什么这不能与List
s工作?
编辑-我使用的是Grails 2.2.0
看一下GORM文档。如果使用List
而不是Set
, Hibernate会在数据库中创建一个clientModelFieldInstances_idx
列。必须填充此列以确保List
中对象的顺序。
来自文档:当使用List时,元素必须在保存之前添加到集合中,否则Hibernate会抛出异常…
尝试使用addTo*方法,而不是手动设置相应的id