web-dev-qa-db-ja.com

Hibernateのload()メソッドのコンテキストでのプロキシとは何ですか?

load() メソッドのHibernateドキュメントには次のように記載されています。

一致するデータベース行がない場合、load()は回復不能な例外をスローすることに注意してください。 クラスがプロキシでマップされている場合、load()は初期化されていないプロキシを返すだけで、プロキシのメソッドを呼び出すまで実際にデータベースにヒットしません。 これは、データベースから実際にロードせずにオブジェクトへの関連付けを作成する場合に便利です。また、クラスマッピングにbatch-sizeが定義されている場合、複数のインスタンスをバッチとしてロードできます。

上記のboldで強調表示されている部分の意味を説明することで、このことを理解してください。

32
Chaitanya

プロキシは、遅延読み込みを支援するためにHibernateによって動的に生成されるクラスです。たとえば、Catクラスがある場合、HibernateはCatを拡張するプロキシクラスを生成します。

このプロキシの初期化されていないインスタンスを取得した場合、Hibernateはまだデータベースにヒットしていないため、IDを除くすべてのフィールドは基本的にnullになります。このプロキシでメソッドを初めて呼び出すと、初期化されていないことが認識され、データベースにクエリを実行して属性をロードします。これは、動的に生成されたクラスが基本クラスのメソッドをオーバーライドし、この初期化/未初期化チェックを追加するために可能です。

Catクラスはプロキシではなく、fatherの関連付けがあると仮定します。Catオブジェクトをロードするとき、Hibernateはそのすべての属性をロードする必要があります。したがって、Catオブジェクトをロードする場合、Hibernateはその父親と父親の父親などもロードする必要があります。プロキシを使用すると、Hibernateは必要なインスタンスのみをロードできます。

Cat cat1 = (Cat) session.load(1);
Cat cat2 = (Cat) session.load(2);
Cat cat3 = (Cat) session.load(3);

cat1.meow(); // this will cause Hibernate to run a query to load cat1's data
cat2.meow(); // this will cause Hibernate to run a query to load cat2's data

// After this cat3 is still an uninitiated proxy because it has not been used

batch-sizeはHibernateの別の機能であり、ほとんどの場合、遅延ロードの処理に役立ちます。基本的には、Hibernateは初期化されていないプロキシを追跡し、初期化が必要な場合に単一のクエリを実行してロードすることです最大batch-sizeプロキシ(1つのプロキシ/クエリだけではなく)

Cat cat1 = (Cat) session.load(1);
Cat cat2 = (Cat) session.load(2);

cat1.meow(); // if batch-size >= 2, cat1 and cat2 will be loaded in a single query
cat2.meow(); // no query will be executed here
66
Guillaume

これは、関連付けの遅延読み込みに似ていますが、「遅延作成」のように見えるかもしれません。

プロキシは、実行時に実装されるサブクラスです。 Hibernateはデータベースを直接クエリする代わりにプロキシ(フェッチされるクラスのサブクラス)を作成し、このプロキシはメソッドの1つが呼び出されるたびにデータベースから「実際の」オブジェクトをロードします。

強調表示されている2番目のテキストは、複数のインスタンスでload()を呼び出すと、それらをバッチとしてフェッチできるため、データベースへのラウンドトリップを削減できることを説明しています。

これは、load()とget()の違いでもあり、オブジェクトの遅延ロードのロードソート、getはデータベースからすぐにオブジェクトをフェッチします

11
Einar Bjerve

プロキシオブジェクトは空のインスタンスで、ゲッターメソッドを使用して要求されたときにオブジェクトフィールドを初期化するためにレイジーロードで使用されます。それまでは、メインIDのみを含むオブジェクトは空です。

2
Mayank Kesari