使用される休止状態のバージョン:
<artifactId>hibernate-annotations</artifactId>
<version>3.5.5-Final</version>
<artifactId>hibernate-core</artifactId>
<version>3.5.5-Final</version>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.2.0.Final</version>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
2 匹の猫 (同じ子猫を持つ猫とその仲間) がいるとしましょう。猫/猫の仲間は、結合列として子猫の名前を持つ子猫との関係を持っています (フェッチ タイプが "eager" の結合列での OneToMany 関係)。
子猫の名前が「big」である猫を取得したいとしましょう。そのために、hql を別の方法で書くことができます。
I.
hql.append("from Cat as cat ")
hql.append("where cat.kitten.name = 'big' ");
II.
hql.append("from Cat as cat inner join cat.kitten as kitten ")
hql.append("where kitten.name = 'big' ");
前述の hql は cat とその子猫の間の内部結合を生成し、期待どおりに機能しています。
しかし、cat がkitten に結合されていないkitten のプロパティ (たとえば location ) を照会したい場合は、次のように hql を記述できます。
III.
hql.append("from Cat as cat ")
hql.append("where cat.kitten.location = 'Chicago' ");
IV.
hql.append("from Cat as cat inner join cat.kitten as kitten ")
hql.append("where kitten.location = 'Chicago' ");
質問 1) III と IV も期待どおりに機能していますが、III は、hql に明示的な結合が記載されていない猫と子猫の間のデカルト/クロス結合を生成していますが、IV はそうではありません。何故ですか?
と
たとえば、2 つの「異なる」オブジェクト cat と mate を mate の名前で hql (関連性がない) に結合したい場合、クロス結合が生成されます。
たとえば、私が言うなら、
V.
hql.append("select cat ")
hql.append("from Cat as cat, Mate mate ")
hql.append("where cat.location = mate.location and mate.location = 'Chicago' ");
クロス ジョインを生成します。
しかし、私が言うなら、
VI.
hql.append("from Cat as cat ")
hql.append("where cat.location in ( select mate.location from Mate mate where mate.location = 'Chicago' ");
質問 2) クロス結合を生成しません。しかし、2 つの列を使用する必要がある場合はどうでしょう。hql によってクロス結合が生成されないようにするには、2 つの in 句を使用する必要があります。なぜ明示的でなければならないのですか?または、可能であればクロス結合を回避するための休止状態の構成はありますか?