質問

APIから、プロキシと関係があることがわかりました。しかし、プロキシに関する多くの情報を見つけることができず、 session.get session.load の呼び出しの違いを理解できません。誰かが私を説明するか、リファレンスページに案内してくれますか?

ありがとう!!

役に立ちましたか?

解決

Hibernateフォーラムから:

  

「Hibernate in Action」という本から。良い方はこれを読んでください。


識別子によるオブジェクトの取得 次のHibernateコードスニペットは、データベースからUserオブジェクトを取得します。

User user = (User) session.get(User.class, userID);

識別子は単一のものを一意に識別するため、get()メソッドは特別です。 クラスのインスタンス。したがって、アプリケーションで識別子を使用するのは一般的です 永続オブジェクトへの便利なハンドル。識別子による取得はキャッシュを使用できます オブジェクトを取得するときに、オブジェクトが既にキャッシュされている場合にデータベースヒットを回避します。 Hibernateはload()メソッドも提供します:

User user = (User) session.load(User.class, userID);

load()メソッドは古いです。 get()はユーザーのためにHibernateのAPIに追加されました 要求。違いは簡単です:

load()がキャッシュまたはデータベースでオブジェクトを見つけられない場合、例外は 投げた。 load()メソッドは決してnullを返しません。 get()メソッドは以下を返します オブジェクトが見つからない場合はnull。

load()メソッドは、実際の永続インスタンスの代わりにプロキシを返す場合があります。 プロキシは、実際のオブジェクトの読み込みをトリガーするプレースホルダーです。 初めてアクセスした;で 一方、get()はプロキシを返しません。 get()とload()の選択は簡単です:永続性が確実な場合 オブジェクトが存在し、存在しない場合は例外とみなされ、load()は 良いオプション。特定の永続インスタンスがあるかどうかわからない場合 識別子、get()を使用して戻り値をテストし、nullかどうかを確認します。 load()を使用すると さらなる含意:アプリケーションは、有効な参照(プロキシ)を取得できます データベースにアクセスせずに永続インスタンスを取得して、永続状態を取得します。そう 永続オブジェクトが見つからない場合、load()は例外をスローしない可能性があります キャッシュまたはデータベース内。例外は、後でプロキシがスローされます アクセスされます。 もちろん、識別子によるオブジェクトの取得は、任意のオブジェクトを使用するほど柔軟ではありません クエリ。

他のヒント

まあ、少なくともnhibernateでは、session.Get(id)はデータベースからオブジェクトをロードしますが、session.Load(id)はサーバーを離れることなくそれにプロキシオブジェクトを作成するだけです。 POCO(またはPOJO :)の他のすべての遅延読み込みプロパティと同様に機能します。その後、このプロキシをオブジェクト自体への参照として使用して、関係などを作成できます。

IDのみを保持し、必要に応じて残りをロードするオブジェクトを持つように考えてください。リレーションシップ(FKなど)を作成するためにそれを渡すだけの場合、必要なのはIDだけです。

session.load()は常に“ proxy”を返します(休止状態用語)データベースにヒットすることなく。 Hibernateでは、プロキシは指定された識別子値を持つオブジェクトであり、そのプロパティはまだ初期化されていません。一時的な偽オブジェクトのように見えます。     行が見つからない場合、ObjectNotFoundExceptionがスローされます。

session.get()は常にデータベースにアクセスし、プロキシではなくデータベース行を表すオブジェクトである実際のオブジェクトを返します。     行が見つからない場合、nullを返します。

これらのメソッドのパフォーマンスもdiffになります。 2つの間...

もう1つの追加ポイント::

Hibernate Sessionクラスのgetメソッドは、オブジェクトがキャッシュとデータベースの両方で見つからない場合、nullを返します。 一方、オブジェクトがキャッシュとデータベースの両方で見つからず、nullを返さない場合、load()メソッドはObjectNotFoundExceptionをスローします。

" load"を使用した場合の間接的な結果" get"の代わりにバージョン属性を使用した楽観的ロックが期待どおりに機能しない場合があるということです。ロードが単にプロキシを作成し、データベースから読み取らない場合、バージョンプロパティはロードされません。バージョンは、後でオブジェクトのプロパティを参照して選択をトリガーする場合にのみロードされます。それまでの間、別のセッションでオブジェクトを更新できます。セッションには、楽観的ロックチェックを行うために必要な元のバージョンがありません。したがって、セッションの更新は、警告なしで他のセッションの更新を上書きします。

これは、同じ識別子を持つオブジェクトで動作する2つのセッションを使用してこのシナリオをスケッチする試みです。 DBのオブジェクトの初期バージョンは10です。

Session 1                  Session 2
---------                  ---------
Load object
Wait a while..   
                           Load object
                           Modify object property
                           [triggers db 'select' -
                            version read as 10]
                           Commit
                           [triggers db update,
                            version modified to 11]
Modify object property
  [triggers db 'select' -
  version read as 11]
Commit
  [triggers db update,
  version modified to 12]

実際にはセッション1のコミットが楽観的ロック例外で失敗するようにしたいのですが、ここでは成功します。

" get"の使用" load"の代わりにgetはすぐにselectを発行し、楽観的ロックチェックの正しい時間にバージョン番号がロードされるため、問題を回避します。

また、オブジェクトが存在しない場合は例外をスローするため、ロードの使用中は注意する必要があります。オブジェクトが存在することが確実な場合にのみ使用する必要があります。

優れた説明は http://にあります。 www.mkyong.com/hibernate/different-between-session-get-and-session-load
session.load():
常に“ proxy”を返します。 (Hibernate用語)データベースにヒットすることなく。
Hibernateでは、プロキシは指定された識別子値を持つオブジェクトであり、そのプロパティはまだ初期化されておらず、一時的な偽オブジェクトのように見えます。
ID値がデータベースに存在しない場合でも、指定されたID値を持つプロキシオブジェクトを常に返します。ただし、データベースからプロパティを取得してプロキシを初期化しようとすると、selectステートメントでデータベースにヒットします。行が見つからない場合、ObjectNotFoundExceptionがスローされます。
session.get():
常にデータベースにヒットし(キャッシュに見つからない場合)、実際のオブジェクト、つまりプロキシではなくデータベース行を表すオブジェクトを返します。
行が見つからない場合、nullを返します。

load()はキャッシュまたはデータベースからオブジェクトを見つけることができず、例外がスローされ、load()メソッドがnullを返すことはありません。

get()メソッドは、オブジェクトが見つからない場合はnullを返します。 load()メソッドは、実際の永続インスタンスではなくプロキシを返す場合があります。get()はプロキシを返しません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top