どのように怠惰な負荷に一対一の構図HQL経由
-
12-09-2019 - |
質問
エンティティBとの双方向の一又はゼロ対1のマッピングとエンティティAを使用している場合
次のようにのマッピングがある:
<class name="EntityA" table="TABLE_A" mutable="true" lazy="true">
<id name="idA" type="long" column="pk_a" unsaved-value="null">
<generator class="sequence">
<param name="sequence">pk_a_seq</param>
</generator>
</id>
<one-to-one name="propertyB" class="EntityB" property-ref="propertyA" constrained="true" outer-join="false"/>
</class>
と
<class name="EntityB" table="TABLE_B" mutable="true" lazy="true">
<id name="idB" type="long" column="pk_b" unsaved-value="null">
<generator class="sequence">
<param name="sequence">pk_b_seq</param>
</generator>
</id>
<many-to-one name="propertyA" class="EntityA" not-null="true" unique="true" lazy="proxy" column="fk_a"/>
</class>
私はエンティティAのためのHQLクエリ(またはむしろ、名前付きHQLクエリ)を行うと、Hibernateは熱心に独立したselect文でエンティティA#propertyBをロードします。
私のHQL 1000エンティティAの(すべてが自分のそれぞれのEntityBのを有する)を返す場合、それと私の問題は、Hibernate、あるでしょうN + 1クエリn個のクエリから来ことでしょうが(第一クエリは、エンティティAは、1000の結果を返すためになりますエンティティA#propertyB)遅延読み込みを選択します。
しかし、私は怠惰な負荷(休止別のSQLクエリを使用することなく)代わりに彼らにしたい理由は、これらのエンティティA#propertyBのことだ必要はありません。
ということは可能ですか?そして、それがある場合、私はそれをどのように行うのですか?
おかげで、 フランツ
解決
私はこの問題を修正しました。
私がやったことは名前エンティティA#propertyBsとセットにフィールドエンティティA#propertyBをオンに作成することでした。しかし、私は、エンティティA#getPropertyB()とエンティティA#setPropertyB(EntityB propertyB)アクセサメソッドを保持します。
これらのアクセサメソッドのメソッド本体は今、このようなものです。
public EntityB getPropertyB() {
return CollectionUtils.get(propertyBs, 0);
}
public void setPropertyBs(EntityB propertyB) {
propertyBs= Collections.singleton(propertyB);
}
その後、私のマッピングでは、私はセットエンティティA#propertyBsをマッピングし、「フィールド」へのアクセスを指定します。
<set name="scheduledAdInfos" lazy="true" fetch="subselect" access="field" cascade="none" inverse="true">
<key column="pk_a"/>
<one-to-many class="EntityB"/>
</set>
この設定では、あなたは今TABLE_AがTABLE_Bによって所有されている場合でも所有POJOに所有POJO(エンティティA)(EntityB)から怠惰なマッピングを作成することができます。
他のヒント
短い答え:いいえ、あなたは、少なくともではないデータベースとのマッピングを変更することなく、それを行うことはできません。あなたは基本的にあなたが望む方法で動作するように1対1のマッピングと外部キーの関係を逆にする必要があります。
<時間>長い答え: 缶遅延ロードの関連付けを休止。それがこれを行う方法は、参照されたオブジェクトのIDを保持しているプロキシオブジェクトを注入することである。
あなたのケースでは、マッピングを使用すると、多対1のマッピングを使用します。ここで、外部キー列は、つまり、TABLE_Bにあるようなものです。あなたはBをロードするのであれば、Hibernateはfk_a列にFKの参照を検出し、この値を保持しているプロキシを作成することができます。プロキシがアクセスされると、対応するエンティティがロードされる。
どのようなテーブルAからレコードが選択されている場合は? Hibenateは、オブジェクトが作成されますが、propertyBを満たすことができるように、それはfk_a = a.idに対応する行を見つけるために、TABLE_Bに見なければなりません。 Hibernateは遅延ロード時にロードするためにどのような記録を見つけるために他の方法はありません。
実際に、また、遅延ロードしながら、他のユニークキーにロードを行うことができるはずので、これは、休止状態のための改良だろうが、現在の実装では、これを許可しない、多分あなたは問題を提起することができます。