3

単純な質問に見えます。私はたくさん理解しようとしましたが、失敗しました。

私の知る限り、Hibernate の最初のレベルのキャッシュはセッション レベルのキャッシュを意味します。同じセッションで同じオブジェクトを複数回取得すると、キャッシュから取得されます。

たとえば、データベースに ID 100 の Employee レコードがあります。

セッションを開いてその従業員オブジェクトを取得しました。セッションを閉じるまで、そのオブジェクトは同じセッションで使用できます。

質問:同じセッションで同じオブジェクトを複数回取得する必要があるのはなぜですか?

4

4 に答える 4

6

私の知る限り、Hibernate の最初のレベルのキャッシュはセッション レベルのキャッシュを意味します。同じセッションで同じオブジェクトを複数回取得すると、キャッシュから取得されます。

半分正解です。あなたが言ったこととは別に、一次キャッシュの主な理由の 1 つは、同じセッションの下で、Hibernate が同じエンティティ (同じ ID を持つエンティティ) が同じオブジェクト インスタンスによって表されることを保証することです。

あなたが言ったことは、セッションからIDでエンティティを取得している場合にのみ正しいです:

Foo foo1 = session.get(Foo.class, 1L);
Foo foo2 = session.get(Foo.class, 1L);

の最初の呼び出しはget()DB に移動して をロードしますFoo。2 番目の呼び出しが呼び出されると、Hibernate はこのセッション内Fooで ID 1 を持つものが既に取得されているかどうかを確認します。以前に取得されたので、Hibernate は単純にそのFooインスタンスを取得して返します。

ただし、このシナリオは、第 1 レベルのキャッシュが有効になる最も一般的な状況ではありません。このことを考慮:

// psuedo code only
User user = findByUserName("ADRIAN");  // assume ID = 777
List<User> users = findAllActiveUsers();

(上記のファインダーが Hibernate セッションを介して内部的にクエリを実行していると仮定します) Hibernate が 2 番目のクエリを実行すると、内部で Hibernate が SQL を実行し、結果セットを取得し、各レコードをユーザーに変換します。アクティブなユーザーの 1 人が ID 777 を持っていると仮定します。Hibernate がそのユーザー オブジェクト インスタンスを構築するとき、最初にそれが第 1 レベルのキャッシュに存在するかどうかをチェックします。以前に (ユーザー名で検索する前のクエリで) 取得されたため、新しい User オブジェクト インスタンスを構築する代わりに、Hibernate は以前に構築した (そして第 1 レベルのキャッシュに保存した) インスタンスを単純に再利用し、結果リストで使用します。

そうすることで、Hibernate は、同じセッション内で、異なる方法で同じエンティティ (同じ ID を持つ同じクラス) を取得した場合、エンティティが同じオブジェクト インスタンスであると常に想定できます。

Orderシステムから sを取得しようとしている、より複雑な例を考えてみてくださいUser。あなたが発見することは、それが(DBで)Order同じを参照するときはいつでも、User実際には同じUserオブジェクトインスタンスを参照しているということです。


の質問に対して

閉じるまでセッションでどのように使用できるか

これは、Hibernate の内部実装の詳細です。ただし、概念的には、各セッションは内部的にマップを持ち、キーはエンティティ タイプ + ID、値はエンティティ オブジェクト インスタンスであると想像できます。

DB からクエリを実行し、セッションがエンティティを構築するときに、エンティティごとに、マップが既に存在する場合はマップから検索します。そうでない場合、セッションはエンティティを構築し、マップに配置します。すでに存在する場合、セッションは単にマップ内のエンティティを利用します

IDでエンティティを取得するときの同様のアイデア(スルーSession.get()などSession.load()

于 2016-09-14T08:48:20.320 に答える
1

EntityManager から同じオブジェクトを何度も取得する必要はありませんが、取得すると同じオブジェクトが取得されます。キャッシングとはこのことです。2 番目の質問について: EntityManager はこのオブジェクトへの参照を保持し、同じオブジェクトを再度要求するとそれを返します。

http://docs.oracle.com/javaee/6/tutorial/doc/bnbpz.htmlのような JPA チュートリアルに取り組むことをお勧めします。私見、JPAの学習に集中し、Hibernateを単にJPAプロバイダーと見なす必要があります。

于 2016-09-14T07:58:26.110 に答える
1

この従業員オブジェクトを取得する必要がある場所で後続の呼び出しが行われた場合は、DB からではなく、同じセッションから取得できます。

于 2016-09-14T08:05:38.903 に答える