説明

上記の戦略とテクニックにはそれぞれ、独自の長所と短所があります。特定の戦略を選択するための一般的な推奨事項は次のようになります。

UNION に基づく TABLE_PER_CLASS 戦略

この戦略は、多態性のクエリと関連付けが必要ない場合に選択するのが最適です。めったに実行しない(またはまったく実行しない)場合は、「ユーザー ユーザーからユーザーを選択」します。User を参照する Entity クラスがない場合は、これが最良のオプションです (最適化された多態性クエリと関連付けを追加できるため)。

SINGLE_TABLE 戦略

この戦略を使用する必要があります。

a) 単純な作業のみ。正規化と NOT NULL 制約が重要な状況では、戦略 3 (JOINED) を優先する必要があります。この場合、継承を完全に放棄して委任に置き換える価値がないのかどうかを考えるのは理にかなっています。

b) ポリモーフィックなクエリと関連付け、および実行時の具象クラスの動的定義が必要な場合。同時に、サブクラスが宣言する新しいフィールドは比較的少なく、スーパークラスとの主な違いは動作にあります。

それに加えて、DBA と真剣に話し合います。

結合戦略

この戦略は、速度と制約の点で最も効率的です。これは、多態性のクエリと関連付けが必要だが、サブクラスが比較的多くの新しいフィールドを宣言する場合に適しています。

ここで注意が必要です。JOINED と TABLE_PER_CLASS の間の決定には、実際のデータに対するクエリ実行プランの評価が必要です。これは、継承階層の幅と深さにより、結合のコスト (そしてその結果としてパフォーマンス) が許容範囲外になる可能性があるためです。

これとは別に、継承アノテーションはインターフェイスには適用できないことを考慮する価値があります。

明示的

データベース内に共有ストレージ戦略を持つエンティティ クラスの階層がある状況も考えられます。しかし、何らかの理由で、基本クラスに対してクエリが実行されたときに一部の階層クラスが返されることは望ましくありません。

これには次のような注釈があります。

@Polymorphism(type = PolymorphismType.EXPLICIT)

これをClientクラスに追加すると、次のようになります。

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@Entity
class User {
  int id;
  String name;
  LocalDate birthday;
}
@Entity
class Employee extends User {
 	String occupation;
 	int salary;
 	LocalDate join;
}
@Entity
@Polymorphism(type = PolymorphismType.EXPLICIT)
class Client extends User {
   String address;
}

その後、HQL クエリは、基本クラスをクエリするときにこのクラスのオブジェクトを無視します。

List<User> accounts = session.createQuery("from User").getResultList();

このクエリは、 UserオブジェクトとEmployeeオブジェクトのリストを返しますが、Client オブジェクトは返しません。