load()
メソッドのHibernateドキュメントには次のように記載されています。
一致するデータベース行がない場合、load()は回復不能な例外をスローすることに注意してください。 クラスがプロキシでマップされている場合、load()は初期化されていないプロキシを返すだけで、プロキシのメソッドを呼び出すまで実際にデータベースにヒットしません。 これは、データベースから実際にロードせずにオブジェクトへの関連付けを作成する場合に便利です。また、クラスマッピングにbatch-sizeが定義されている場合、複数のインスタンスをバッチとしてロードできます。
上記のboldで強調表示されている部分の意味を説明することで、このことを理解してください。
プロキシは、遅延読み込みを支援するために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
これは、関連付けの遅延読み込みに似ていますが、「遅延作成」のように見えるかもしれません。
プロキシは、実行時に実装されるサブクラスです。 Hibernateはデータベースを直接クエリする代わりにプロキシ(フェッチされるクラスのサブクラス)を作成し、このプロキシはメソッドの1つが呼び出されるたびにデータベースから「実際の」オブジェクトをロードします。
強調表示されている2番目のテキストは、複数のインスタンスでload()
を呼び出すと、それらをバッチとしてフェッチできるため、データベースへのラウンドトリップを削減できることを説明しています。
これは、load()とget()の違いでもあり、オブジェクトの遅延ロードのロードソート、getはデータベースからすぐにオブジェクトをフェッチします
プロキシオブジェクトは空のインスタンスで、ゲッターメソッドを使用して要求されたときにオブジェクトフィールドを初期化するためにレイジーロードで使用されます。それまでは、メインIDのみを含むオブジェクトは空です。