質問

「プレイヤー」と「アイテム」という 2 つのテーブルがあります。プレイヤーはアイテムのリストを持っています。ページネーションを使用して、プレーヤーとそのすべてのアイテムを取得したいと考えています。アイテムの数に関係なく、プレイヤーに基づいてページネーションをしたいと考えています。

そこで私は次のようなことをします:

Criteria c = session.createCriteria(Players.class).setFetchMode("items", FetchMode.JOIN);
c.addOrder(Order.asc("playerID"));
c.setFirstResult(0);
c.setMaxResults(25);
List<Player> players = c.list();

これにより、最初の 25 人のプレイヤーが提供されるのでしょうか、それとも最初の 25 個のアイテム (プレイヤーごとにグループ化された) が提供されるのでしょうか?この動作は JPA クエリの場合と同様に未定義なのか、それとも保証された答えがあるのか​​疑問に思っています。

それはともかく、最初の 25 人のプレイヤー、または最初の 25 人のプレイヤーとアイテムの組み合わせ (プレイヤー ID、アイテム ID の順) を取得する条件クエリとは何ですか?

役に立ちましたか?

解決

確かに、100% ではありませんが、次のことが行われます。

プレイヤーとアイテムを結合し、playerID で並べ替え、最初の 25 件の結果をすべて 1 つの SQL クエリで取得します。このデータからプレーヤーとアイテムが作成され、合計 25 個のアイテムを持つ任意の数 (25 人以下) のプレーヤーが生成されます。最後のプレイヤーがすべてのアイテムを取得できない場合があります。

25 人のプレイヤーを獲得するには、次のことを避けてください。 FetchMode.JOIN (N+1 問題を回避するには、マッピング ファイルでバッチサイズを使用します):

List<Player> first25Players = session
  .createCriteria(Players.class)
  .addOrder(Order.asc("playerID"))
  .setMaxResults(25)
  .list();

25 個のアイテムを取得するには、プレーヤーではなくアイテムでクエリを開始します。

List<Item> first25Items = session
  .createCriteria(Item.class)
  .addOrder(Order.asc("player")) // assuming that player is available
  .setMaxResults(25)
  .list();

アイテムからプレーヤーへのナビゲーションがない場合は、ナビゲーションを追加できます。

他のヒント

Hibernate の「高度な問題」に関する FAQ から:

http://community.jboss.org/wiki/HibernateFAQ-AdvancedProblems

また、SetFirstreSult(5)やSetMaxResults(10)などのResultSet Rowベースの「制限」操作が、この種の熱心なフェッチクエリでは機能しない理由も明らかです。結果セットを特定の数の行に制限すると、データをランダムに遮断します。ある日、Hibernateは、setFirstreSult()またはsetMaxResults()を呼び出すと、結合を使用しないでください。それを試してください、あなたのバージョンのhibernateはすでに十分に賢いかもしれません。そうでない場合は、2つのクエリを作成します。1つは制限用に、もう1つは熱心なフェッチをするために書きます。

つまり、Hibernate はこれをサポートしていません。賢明で Hibernate がどのように実装されているかを知っていれば、setFirstResult と setMaxResults がどのような場合でもページネーションなどのリモート操作を実行しないことが明らかだったはずです。それは明白だったので文書化する必要はありません。

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