1

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 を使用しています

4

1 に答える 1

3

GORM docsを見てください。HibernateのList代わりにを使用すると、データベースに列が作成されます。内のオブジェクトの順序を確認するには、この列に入力する必要があります。SetclientModelFieldInstances_idxList

ドキュメントから:リストを使用する場合、保存する前に要素をコレクションに追加する必要があります。そうしないと、Hibernate は例外をスローします ...

対応する ID を手動で設定する代わりに、 addTo*メソッドを使用してみてください。

于 2013-03-12T16:06:46.987 に答える