0

こんにちは、単純な翻訳リストを実装しようとしています。つまり、値とこの値への翻訳があります。

[編集:] これは私のユーザー インターフェースの一部であり、値と翻訳は xml 経由でエクスポート可能であるため、i18n ファイルの継ぎ目を使用すると、この命題にはかなり不便です。そのため、それらをデータベースに保存することにしました。

値に対して 1 つのドメイン クラスがあります。

class Value {
    String label
    static hasMany = [ translations: Translation ]
}

1 つの値に対して、特定の言語に対して複数の翻訳が存在してはならないことを保証する一意の制約を持つ翻訳用の 1 つ:

class Translation {
    String value
    Language language

    static belongsTo = [ value: Value ]

    static constraints = {
        language(unique: 'value')
    }
}

私の問題は、同じ値に対して 2 つの翻訳言語を交換した後に発生します。例:

value.translations.each() { translation ->
    println "${value.label} in ${translation.language.label} is ${translation.value}"
}

// process updates...

value.translations.each() { translation ->
    println "${value.label} in ${translation.language.label} is ${translation.value}"
}

// validate...

プリントアウト

Comedy in german: Comedy
Comedy in english: Komödie   

Comedy in english: Comedy
Comedy in german: Komödie

したがって、更新の前後で一意の制約に違反することはありませんが、とにかく保存中に一意の制約に失敗します。もう1つの奇妙なことは、値に対して each() ループを実行したときにのみこのエラーが発生することです。内容を検査しないと、検証はパスし、save(flush:true) メソッドは true を返しますが、値はデータベースで変更されません。

[編集:] 1 つの値のみが変更され、もう 1 つの値が変更されていない場合、問題はデータベース レベルにあると思います。まさにその状態で制約に違反しているためです。代わりに変更がトランザクションとして実行され、この中間ステップで制約がチェックされない場合、これを回避できます。(これは私が探しているものかもしれません)

これを回避する別の方法は、編集されたすべての Bean を削除して再作成することですが、これを行うためのより便利な方法があることを望んでいました。

助けてくれてありがとう

4

1 に答える 1

1

暗黙的または明示的な制約が発生すると、制約がチェックされますflush()その時点で、GORMはデータベースにそのような値が他に存在するかどうかを確認します。そのため、1 つのインスタンスが既にflush()編集されていて、別のインスタンスがまだ作成されていない場合、制約違反が発生します。

flush()トランザクションの最後までしないようにしてください-flush: trueパラメータを削除するか、または に設定しflush: falseます。トランザクションの最後に、両方の変更が適用されます。

Grails、JFYTK には警告があります。それは、実行時に暗黙的flush()に実行するCriteriaため、まだ意図していないときに Hibernate エラーに驚かないでくださいflush()

于 2011-05-30T12:44:10.737 に答える