A
とB
の2つのエンティティがあります。それらは関連していますが、関係マッピングをBeanに追加したくありません。
HQLまたは基準を使用してA
とB
の間に左外部結合を使用するにはどうすればよいですか?
これにはいくつかの回避策がありますが、
私は常にこれら2つのオプションに戻っていましたが、これに代わるものはありますか?またはこれは不可能ですか?
現在、HQLを使用してwhere句で無関係なクラスを結合するthetaスタイルは、内部結合のみをサポートしています。
request このような状況で外部結合をサポートすることは 現在3番目に投票数が多い拡張機能 ですが、この機能が近い機能に実装されるとは思わない 現在のANTLERベースのクエリパーサーの再実装 が必要です。これは巨大なタスクIMOのようです。
AとBの関係を追加せずにHQLを使用して左結合を実行することを主張する場合、オプション3を使用して最初に内部結合を実行し、次のHQLを使用できます
from A a where a.some not in ( select b.some from B)
bに参加できないすべてのAを見つけ、プログラムで結果を結合する。
更新
リリース5.1.0から HHH-16(無関係なクラスでの明示的な結合) が修正され、無関係なエンティティを結合できるはずです。
Ken Chanが言ったように、1つのHQLクエリで直接行うことはできません。
あなたの3つの可能性に関して:
何らかの特別な理由でリレーションシップを本当に追加したくない場合は、クエリを2つの個別のクエリに分割し、次のようにJavaで結果を手動で結合できます。
Query qa = session.createQuery("from A a");
List la = qa.list();
Query qb = session.createQuery("select distinct b.* from B b, A a where a.some=b.some");
List lb = qb.list();
Map bMap = new HashMap();
for (B b : lb) {
bMap.put(b.getId(), b);
}
/* example with for loop */
for (A a : la) {
B b = bMap.get(a.getForeignKeyForB());
/* now you have A a and the outer joined B b and you can do with them what you want */
...
}
このソリューションの実行時間とメモリのコストは、データベースの外部結合とほぼ同じです(ソリューション2)。もう少しJavaコード。
(この解決策はKen Chanが提案したものと似ていますが、「not in」と内部選択を回避しています。どちらもデータベースでは非効率的です。)
すべてのAに最大1つのBがあることがわかっている場合は、サブクエリも使用できます。
例えば:
select a, (select b from B b where b.some = a.some)
from A a
少なくとも1つのBが存在することがわかっている場合は、次のクエリも使用できますが、ハックであるためお勧めできません。
select a, (select b4 from B b4 where b4=b and b4.some=a.some) from A a, B b
where a.some=b.some or (a.some not in (select b2.some from B b2)
and b.id = (select min(b3.id) from B b3))