Grails - 拥有关系的一方在使用List时不会持久存在

时间:2013-03-12 13:44:12

标签: hibernate grails gorm one-to-many

我在尝试持久保存两个实体之间的关联时遇到了一个奇怪的问题。当我使用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 ]
}

在Bootstrap.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.client具有正确的值但是一旦调用modelFieldInstance.save(),我得到一个异常,说modelFieldInstance.client为null -

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

1 个答案:

答案 0 :(得分:3)

查看GORM docs。如果您使用List而不是Set Hibernate在数据库中创建clientModelFieldInstances_idx列。必须填写此列以确保List

中对象的顺序

从文档:使用List时,必须在保存之前将元素添加到集合中,否则Hibernate将抛出异常......

尝试使用addTo*方法,而不是手动设置相应的ID。