120

また、LazyLoadExceptions を回避するために、どのような代替戦略を使用していますか?

ビューで開いているセッションには次の問題があることを理解しています。

  • 異なる jvm で実行される階層化されたアプリケーション
  • トランザクションは最後にのみコミットされ、ほとんどの場合、前に結果が必要になります。

しかし、アプリケーションが単一の vm で実行されていることがわかっている場合は、オープン セッション イン ビュー戦略を使用して問題を緩和してみませんか?

4

9 に答える 9

47

初期化されていない可能性のあるプロキシ、特にコレクションをビューレイヤーに送信し、そこから休止状態の読み込みをトリガーすることは、パフォーマンスと理解の両方の観点から問題になる可能性があるためです。

理解:

OSIV を使用すると、ビュー レイヤーがデータ アクセス レイヤーに関連する問題で「汚染」されます。

ビューレイヤーは、遅延読み込み時に発生する可能性のある a を処理する準備ができてHibernateExceptionいませんが、おそらくデータアクセスレイヤーは処理されています。

パフォーマンス:

OSIV は、適切なエンティティの読み込みをカーペットの下に引っ張る傾向があります。コレクションまたはエンティティが遅延して初期化されていることに気付かない傾向があります (おそらく N+1 )。より便利に、より少ないコントロール。


更新:この件に関するより大きな議論については、OpenSessionInView アンチパターンを参照してください。著者は、次の 3 つの重要な点を挙げています。

  1. 各遅延初期化は、各エンティティが N + 1 クエリを必要とすることを意味するクエリを取得します。ここで、N は遅延関連付けの数です。画面に表形式のデータが表示されている場合、Hibernate のログを読むことは、すべきことをしないという大きなヒントです。
  2. プレゼンテーション層のDBで爪を汚すので、これは階層化アーキテクチャを完全に打ち負かします. これは概念的な短所なので、問題なく使用できますが、当然の帰結があります。
  3. 最後になりましたが、セッションのフェッチ中に例外が発生した場合、それはページの書き込み中に発生します。ユーザーにクリーンなエラー ページを提示することはできず、できることは本文にエラー メッセージを書き込むことだけです。
于 2009-07-09T11:52:26.943 に答える
24
  • トランザクションはサービス レイヤーでコミットできます。トランザクションは OSIV とは関係ありません。実行中のSessionトランザクションではなく、開いたままです。

  • アプリケーション層が複数のマシンに分散している場合、OSIV はほとんど使用できません。オブジェクトをネットワーク経由で送信する前に、必要なものをすべて初期化する必要があります。

  • OSIV は、遅延読み込みのパフォーマンス上の利点を利用するための優れた透過的な (つまり、コードのどれもそれが発生したことを認識していない) 方法です。

于 2010-09-21T12:44:50.897 に答える
13

Open SessionInViewが悪い習慣と見なされているとは言えません。何があなたにその印象を与えますか?

Open-Session-In-Viewは、Hibernateでセッションを処理するためのシンプルなアプローチです。単純なので、単純な場合もあります。リクエストに複数のトランザクションを含めるなど、トランザクションをきめ細かく制御する必要がある場合、Open-Session-In-Viewが常に適切なアプローチであるとは限りません。

他の人が指摘しているように、OSIVにはいくつかのトレードオフがあります。開始するトランザクションを認識しにくいため、N+1の問題が発生しやすくなります。同時に、ビューの小さな変更に適応するためにサービスレイヤーを変更する必要がないことを意味します。

于 2009-07-21T15:57:33.410 に答える
5

Spring などの Inversion of Control (IoC) コンテナーを使用している場合は、bean scopingを読みたいと思うかもしれません。基本的に、私は Spring にSession、ライフサイクルがリクエスト全体に及ぶ (つまり、HTTP リクエストの開始時と終了時に作成および破棄される) Hibernate オブジェクトを提供するように指示しています。LazyLoadExceptionIoC コンテナーがそれを管理してくれるので、s やセッションを閉じることを心配する必要はありません。

前述のように、N+1 SELECT のパフォーマンスの問題について考える必要があります。後で Hibernate エンティティをいつでも構成して、パフォーマンスが問題になる場所で熱心な結合読み込みを行うことができます。

Bean スコープ ソリューションは、Spring 固有のものではありません。PicoContainer が同じ機能を提供していることは知っていますし、他の成熟した IoC コンテナーが同様の機能を提供していると確信しています。

于 2009-07-20T11:44:10.047 に答える
4

私自身の経験では、OSIV はそれほど悪くはありません。私が行った唯一の取り決めは、2 つの異なるトランザクションを使用することです。

于 2010-10-13T14:40:47.583 に答える
3

ブログでオープン セッション イン ビューをいつ使用するかについて、いくつかのガイドラインを投稿しました。興味のある方はチェックしてみてください。

http://heapdump.wordpress.com/2010/04/04/should-i-use-open-session-in-view/

于 2010-04-04T01:12:02.090 に答える
1

私はHibernateでv.さびています..しかし、1つのHibernateセッションで複数のトランザクションを持つことは可能だと思います。したがって、トランザクションの境界は、セッションの開始/停止イベントと同じである必要はありません。

OSIV、imo、主に便利なのは、リクエストが DB アクセスを行う必要があるたびに「永続コンテキスト」(別名セッション) を開始するためのコードを書く必要がなくなるためです。

サービス レイヤーでは、「Required、New Required など」など、さまざまなトランザクション ニーズを持つメソッドを呼び出す必要があるでしょう。これらのメソッドが必要とする唯一のことは、誰か (つまり、OSIV フィルター) が永続化コンテキストを開始したことだけです。そのため、彼らが心配しなければならないことは、「ねえ、このスレッドの休止状態セッションをくれ..私はいくつかのことをする必要がある. DBのもの」。

于 2009-11-02T18:25:55.153 に答える
1

これはあまり役に立ちませんが、ここで私のトピックを確認できます: * Hibernate Cache1 OutOfMemory with OpenSessionInView

OpenSessionInView と多くのエンティティがロードされているため、いくつかの OutOfMemory の問題があります。それらは Hibernate キャッシュ レベル 1 にとどまり、ガベージ コレクションされないためです (1 ページあたり 500 アイテムのエンティティを多数ロードしますが、すべてのエンティティはキャッシュに残ります)。

于 2011-01-21T13:58:34.673 に答える