hibernateを使用するSpringFrameworkに基づくWebアプリケーションのコントローラーでこの例外が発生します。私はこれに対抗するために多くの方法を試みましたが、それを解決することができませんでした。
コントローラのメソッドではhandleRequestInternal
、送信アクションがない限り、主に「読み取り」のためにデータベースに対して呼び出されます。私はSpring'sSessionを使用してきましたが、移動しましたがgetHibernateTemplate()
、問題はまだ残っています。
基本的に、これはデータベースへの2回目の呼び出しで、この例外をスローします。あれは:
1)getEquipmentsByNumber(number)
{最初に、プロパティのリストがあり、各プロパティに値のリストがある「番号」に基づいて、機器がDBからフェッチされます。これらの値(プリミティブオブジェクトの文字列)をループして変数に読み込みます)
2)getMaterialById(id)
{idに基づいてマテリアルをフェッチします}
2番目の呼び出しは、おそらく「フラッシュ」するセッションを行っていることを理解していますが、私はオブジェクトを「読み取っている」だけです。何も変更されていない場合、2番目の呼び出しがEquipmentプロパティで古いオブジェクト状態の例外をスローするのはなぜですか。 ?
ビューに渡すオブジェクトでLazyExceptionsが発生するため、呼び出し後にキャッシュをクリアできません。
私はこれを読みました: https ://forums.hibernate.org/viewtopic.php?f = 1&t = 996355&start = 0 しかし、提供された提案に基づいて問題を解決できませんでした。
この問題を解決するにはどうすればよいですか?任意のアイデアや考えをいただければ幸いです。
更新:
私が今テストしたのはgetEquipmentsByNumber()
、プロパティのリストから変数を読み取った後の関数で、これを行うことです:getHibernateTemplate().flush();
そして今、例外は、マテリアルをフェッチするための呼び出しではなく、この行にあります(つまりgetMaterialById(id)
)。
更新: flushを明示的に呼び出す前に、セッションキャッシュからオブジェクトを削除して、古いオブジェクトがキャッシュに残らないようにします。
getHibernateTemplate().evict(equipment);
getHibernateTemplate().flush();
さて、これを行った後、問題はDBからの次のフェッチに移りました。メソッドに同期済みのラベルを付け、内容を読み終えたらすぐにオブジェクトを削除する必要があると思います。あまり良く聞こえません。
更新:
メソッドhandleRequestInternal
を「同期」しました。エラーは消えました。もちろん、最善の解決策ではありませんが、何をすべきか!handleRequestInternal
現在のセッションを閉じて、新しいセッションを開くことを試みました。ただし、アプリの他の部分が正しく機能しなくなる可能性があります。ThreadLocal
どちらも機能しなかったものを使おうとしました。