2

次のドメイン クラスを考慮します。

class EnrichmentConfig {

    String name
    String description
    String concept
    List fields = []

    static hasMany = [fields: FieldConfig]

    static constraints = {
        name(maxSize: 60, blank: false, nullable: false, unique: true)
        concept(maxSize: 255, blank: false, nullable: false)
        description(nullable: true, blank: true)
        fields(nullable: false, validator: { fields, enrichmentConfig ->
            if (fields?.isEmpty()) {
                return ['empty']
            } else {
                return true
            }
        })
    }

    static mapping = {
        description(type: 'text')
        fields(cascade: "all-delete-orphan")

        sort('name')
    }
}

class FieldConfig {

    List providers = []

    static hasMany = [providers: String]

    static belongsTo = [mainConfig: EnrichmentConfig]

    static constraints = {

        providers(nullable: false, validator: { providers, fieldConfig ->
            // some custom validation
        })
    }

    static mapping = {
        providers(cascade: 'all-delete-orphan', lazy: false)
    }
}

EnrichmentConfig関連付けられたコントローラーのインスタンスを更新するために使用するコードは次のとおりです。

def update = {

    def enrichmentConfig = EnrichmentConfig.get(params.long('id'))
    if (enrichmentConfig) {

        enrichmentConfig.properties = params

        if (enrichmentConfig.validate()) {
            if (enrichmentConfig.save(flush: true, failOnError: true)) {
                    flash.message = "${message(code: 'enrichmentConfig.updated.message', args: [enrichmentConfig.name])}"
                    redirect(controller: 'enrichment')
                }
        } else {
            // re-validation to attach an error object to each eroneous fieldConfig
            enrichmentConfig.fields?.each { it.validate() }
        }
        render(view: 'fields', model: getFieldsModel(enrichmentConfig))
        return
    } else {
        flash.message = "${message(code: 'enrichmentConfig.not.found.message', args: [params.id])}"
        redirect(controller: 'enrichment')
    }
}

EnrichmentConfigのインスタンスを更新することを検証すると、関連付けられFieldConfigたインスタンスが無効であるにもかかわらず、予期せずデータベースに保存されることに気付きました。実際、debug ste-by-step モードで をenrichmentConfig.validate()実行すると、コンソールに次のように表示されます。

    Hibernate: 
    update
        field_config_providers 
    set
        providers_string=? 
    where
        field_config_id=? 
        and providers_idx=?

これはどのように起こりますか?私は何を間違っていますか?grails 1.3.7 を使用していることを明記する必要があります。

よろしくお願いします。

4

2 に答える 2

0

オブジェクトを保存するサービスを使用することをお勧めします。まず、validate() メソッドを使用して、すべてのオブジェクトの有効性を確認します。

次に、依存する順序または従う階層でオブジェクトを保存します。

于 2013-01-29T09:05:07.537 に答える
0

これは単なる推測ですが、おそらくどこかから始めるべきです。Hibernate がいつセッションをフラッシュし、データを部分的に保存するなどを決定するかを理解するふりはしません。しかし、私が知っていることは、すべての書き込み関連の呼び出しをサービスに入れることで、時間の経過とともに多くの悲しみを軽減できるということです。

update メソッドの一部をサービスに移動してみて、うまくいくかどうかを確認してください。私の推測では、hibernate は他のことを行うためにデータの一部を永続化する必要があり、それがトランザクション サービスにある場合、RuntimeException がスローされると書き込みがロールバックする可能性があります。

于 2012-06-07T15:12:32.903 に答える