2 つのエンティティ間の関連付けを保持しようとすると、奇妙な問題が発生します。(つまり Grails のデフォルト) を使用Set
すると動作しますが、 を使用しようとする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 で、1 つの Client と 1 つの 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 を使用しています