2

使用される休止状態のバージョン:

  <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 句を使用する必要があります。なぜ明示的でなければならないのですか?または、可能であればクロス結合を回避するための休止状態の構成はありますか?

4

1 に答える 1

0

最初の形式(I、III、V)では、テーブル間の結合条件はマッピングで定義されます(おそらく、、、<one-to-many>または句で)<many-to.one>。例では、あなたは正しいものを定義したようですが、IIIとVでは正しく定義していません。<one-to-one><many-to-many>

例II、IV、およびVIでは、結合(または副選択)を明示的に定義しました。HQLステートメントに結合がある場合、Hibernateは常にこの結合を単一のSQLステートメントで使用します(結合がマッピングで定義されている場合はそうではありません-Hibernateは2つの独立した選択を優先することがよくあります(遅延読み込みはその場合にのみ機能します)) 。これは、a)マッピング内のテーブル間に結合がなく、where条件に2番目のテーブルが必要な場合、またはb)2つの異なるステートメントを使用する代わりに、休止状態を1つのステートメントに直接結合するように強制する場合のパフォーマンス上の理由で役立ちます。 。

IIIとVが機能せず、デカルト積を生成する理由を説明する場合は、テーブルのマッピングを提供する必要があります。

于 2012-06-14T07:34:59.677 に答える