0

Grails アプリケーションを Oracle から MySQL データベースに移植しています。元の Oracle バージョンは、MySQL にはない Oracle の INSTEAD OF INSERT OR UPDATE 機能を利用するいくつかの複雑なビューを使用するレガシー データベースです。回避策として、これらの種類のビューを指す Domain クラスに Insert メソッドと Update メソッドを実装しました。例えば、

class AdminUser {
    //...
    def update() {
        if(this.validate()) {
            Sql sql = Utils.getHibernateSql()

            sql.execute(
                "update table_x ...",
                [...]
            )

            sql.execute(
                "update table_y ...)",
                [...]
            )

            sql.execute(
                "update table_z ...",
                [...]
            )

            return true
        }

        return false
    }
    //...
}

現時点で私が直面している問題の説明は次のとおりです。

  1. サービス メソッド内で、AdminUser.get を使用して AdminUser のインスタンスをロードします。
  2. ロードされたインスタンスを変更して update() を呼び出すと、すべて問題なく表示されます
  3. サービス メソッドの実行が終了すると、インスタンスで save を呼び出す何かが原因で例外がスローされます。

ステップ (3) で魔法のような保存が行われるのを防ぐにはどうすればよいでしょうか (最近どこかで、Grails が変更されたドメイン クラス インスタンスをサービス メソッドの終了時にまだ保存されていないものとして自動的に保存するという記事を読みましたが、今すぐそのリソースにリンクしてください)?

4

2 に答える 2

2

変更されたインスタンスをダーティフィールドを使用してHibernateセッションに残します。save()Hibernateセッションがフラッシュされると、通常の方法でオブジェクトを再度保存しようとします。

1つの解決策は、変更を手動で保存した後、休止状態のセッションからオブジェクトを破棄することです。例えば:

def update() {
    if(this.validate()) {
        Sql sql = Utils.getHibernateSql()

        sql.execute(
            "update table_z ...",
            [...]
        )

        ...

        this.discard()  // remove the object from the hibernate session
        return true
    }

さらに、これをConfig.groovyに追加して、オブジェクトを明示的に保存するように要求できます。

hibernate.flush.mode="manual"
于 2010-10-12T17:36:50.413 に答える
0

get() の代わりに read() を使用すると、オブジェクトは変更を自動保持しません。save() を明示的に呼び出すことはできますが、OpenSessionInView インターセプターが保存されていないすべてのダーティ インスタンスをフラッシュする標準的な動作では、read() で読み込まれたインスタンスはスキップされます。

于 2010-10-12T17:50:27.827 に答える