クラスおよび@DiscriminatorValueで@DiscriminatorColumnをサブクラスで使用する場合、Hibernateが生成するSQLは、ディスクリミネータ列を含む句のリテラルとしてディスクリミネータ値を使用します。Hibernate discriminatorの値にリテラルの代わりにバインド変数を使用する
例:
select this_.person_id as y0_ from name this_ where this_.part_type='GIV'
これはあなたまで、それほど悪いわけではない:私はクラス以外には基準とシンプルな基準クエリを作成する場合
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "PART_TYPE")
@Table(name = "NAME")
public class NamePartEntity implements Comparable<NamePartEntity> {
// Stuff
}
@Entity
@DiscriminatorValue(value = "GIV")
public class GivenNameEntity extends NamePartEntity {
// stuff
}
が、私はSQLは、のように生成さになるだろういくつかの識別器の値を持ち、テーブルを複数回選択して、以下のようなクエリを得ることができます。
SELECT this_.person_id AS y0_
FROM name this_
WHERE this_.part_type='FAM'
AND this_.value_u =:8
AND this_.tenant_id =:9
AND this_.person_id IN
(SELECT this_.person_id AS y0_
FROM name this_
WHERE this_.part_type='GIV'
AND this_.value_u =:10
AND this_.tenant_id =:11
AND this_.person_id IN
(SELECT this_.person_id AS y0_
FROM name this_
WHERE this_.part_type='GIV'
AND this_.value_u =:12
AND this_.tenant_id =:13
AND this_.person_id IN
(SELECT this_.person_id AS y0_
FROM name this_
WHERE this_.part_type='PFX'
AND this_.value_u =:14
AND this_.tenant_id =:15
)
)
)
は、リテラル(この場合は 'FAM'、 'GIV'、 'PFX')に基づいて、さまざまなSQL IDと実行計画を持つことができますが、それらは異なる可能性があります。ただし、これらのディスクリミネータ値リテラルの代わりにバインド変数が使用されている場合は、同じSQL IDで同じ実行計画が適用されます。
したがって、Hibernateでリテラルの代わりにバインド変数が使用されるように、discriminatorのcolumn/valueアノテーションを使用することは可能ですか?これを避けるためにエンティティを書き換えることは可能ですが、既存のアノテーションでバインド変数の機能を何らかの方法で取得できるかどうかを確認したいと考えました。
また、ディスクリミネータ値を使用せずに拡張クラスを使用する方法はありますか?それを試して、各拡張クラスに@Entity注釈を付けると、それは、弁別子注釈がない場合でも、識別子タイプの欠落について苦情を言います。
これはすべて生成(動的)SQLですか?そうでなければ、cursor_sharing = FORCEを設定して、すべてのリテラルをシステム・バインドに変換することができます。 – sandman
これがOracleの場合、cursor_sharing = FORCEは機能しますが、一般的には推奨されません。本番環境で実装する前に2回考えてください! – user2612030
@sandmanこれは動的クエリであり、これはOracleであるが、とにかく移動していく予定である。しかし、誰かが役に立つと思うかもしれないので、入力に感謝します。 – AHungerArtist