3

ここのHQL初心者は、これに本当に苦労しています。

次の3つのクラスがあるとしましょう:

public class A {
int id;
B b;
}

public class B {
int id;
Set<C> c;
}

public class C {
int id;
String type;
}

テーブル B には、テーブル b_c によって定義された C との多対多の関係があります。テーブル A から選択し、C.id でグループ化し、C.type = 'desiredType' でフィルター処理し、C オブジェクトと A.id の数を返すクエリが必要です。私は次のようなもので遊んでいます:

SELECT c, COUNT(a.id) as count from A a JOIN a.b.c as c WHERE c.type = 'desiredType' GROUP BY c.id ORDER BY COUNT(a.id) desc

このクエリのさまざまな繰り返しを試してみましたが、さまざまな例外が発生し続けるか、クエリから何も返されません。私が理解していないように見える主な問題は、正しい型に一致するコレクションの個々のオブジェクトを返す方法です。

この質問が愚かに聞こえないことを願っています。HQL のマニュアルとその他の 100 の SO の質問を読みましたが、何かが欠けているに違いありません。ご指導いただきありがとうございます。

4

1 に答える 1

2

あなたがやりたいことは、このようには機能しません。最後に、A と B から選択しますが、条件に適合する Bc のサブセットのみを選択します。これは不可能です。Hibernate は完全なセット c のみをロードできます (100% 正しいわけではありません。マッピングで選択を制限できますが、ここでは解決策ではありません)。このように、おそらく要件を満たさない可能性があります。exists 句で制限されたすべての A をロードし、手動でカウントします。

FROM A a where EXISTS (SELECT 1 FROM C, B_C
                          WHERE C.type = 'desiredType'
                             AND B_C.c_id = C.id
                             AND B_C.b_id = a.b.id)

次に、A のインスタンスであるリストのすべての要素をループで通過する必要があります。その C が目的のタイプである場合は、すべての abc の内部ループをチェックインします (まだ実行する必要があります。上部の選択は制限するだけです)。目的のタイプの C が少なくとも 1 つある A への選択ですが、リストにはこれらの A のすべての C があり、正しい c.id のカウントを設定します。

このソリューションの欠点は、型が間違っていてもすべての C が読み込まれ、すべてのカウントを Java コードで行う必要があることです。したがって、そのソリューションが気に入らない場合があります。

より良い解決策は次のとおりです。

テーブル C から考え始めます。クラス C に を追加しますSet <B> b;(これは多対多の関係です。おそらく、結合テーブル B_C を Java クラスとして定義する方が便利です)。クラス B では、テーブル A へのアクセスを追加しますA a(B:A が 1:1 の関係の場合) またはSet<A> a(B:A が 1:n の関係の場合)。次に、目的の C: を選択するだけです。

FROM C WHERE C.type = 'desiredType'

countA = c.b.size()(A と B の間の 1:1 関係) またはcountA = 0; for (B b : c.b) {countA += b.a.size()}(A と B の間の n:1 関係)によって選択された各 c に対して Java で取得した C.id による A グループの数。

于 2013-03-05T08:04:17.070 に答える