1

尝试保持两个实体之间的关联时,我遇到了一个奇怪的问题。当我使用 a Set(即 Grails 默认值)时,它可以工作,但是如果我尝试使用 a 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 中,我正在创建一个 Client 和一个 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 方法用于为每个 Client 创建空的 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]
}

然后正确地保持关联。为什么这不适用于Lists?

编辑 - 我正在使用 Grails 2.2.0

4

1 回答 1

3

看看GORM 文档。如果您使用 aList而不是SetHibernate ,则会clientModelFieldInstances_idx在数据库中创建一列。必须填写此列以确保您的List.

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

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

于 2013-03-12T16:06:46.987 回答