Play Framework 1.2.4をPostgreSQL
およびJPA
と共に使用しています。モデル階層を持ち、これを行うためのいくつかの代替手段があることを確認したいと思います。
基本クラス(抽象)と、この基本クラスを拡張する2つの具象クラスがあります。具体的なクラスが必要な間は、この基本クラスを永続化したくありません。基本クラスには、プロパティとして別のモデルクラスがあります。つまり、基本クラスには@ManyToOne
関係があります。
私の質問は、これを実装する最良の方法は何ですか? @MappedSuperclass
または@Inheritance
戦略でTABLE_PER_CLASS
を使用していますか? 事実上同等と思われるため、少し混乱しています。
また、クエリやパフォーマンスの問題について、将来直面する可能性のある懸念もあります。
プロパティ、関連付け、およびメソッドを継承するには、MappedSuperClassを使用する必要があります。
エンティティといくつかのサブエンティティがある場合、エンティティの継承を使用する必要があります。
次の質問に答えることで、どちらが必要かを判断できます。モデルに基本クラスとの関連付けが可能な他のエンティティがありますか?
はいの場合、基本クラスは実際にはエンティティであり、エンティティの継承を使用する必要があります。いいえの場合、基本クラスは実際にはいくつかの無関係なエンティティに共通の属性とメソッドを含むクラスであり、マップされたスーパークラスを使用する必要があります。
例えば:
この記事 で説明したように、_@MappedSupperclass
_は_@Inheritance
_アノテーションとは異なります。
_@MappedSuperclass
_は、_@MappedSuperclass
_アノテーションが付けられたスーパークラスを拡張する子クラスによって宣言されているかのように、基本クラスの永続プロパティを含めるようJPAプロバイダーに指示します。
ただし、データベースの観点からは基本クラスが示されていないため、継承はOOPワールドでのみ表示されます。子クラスエンティティのみに関連付けられたマッピングテーブルがあります。
_@Inheritance
_アノテーションは、データベーステーブル構造内でOOP継承モデルを具体化することを目的としています。さらに、_@Inheritance
_アノテーションが付けられた基本クラスをクエリできますが、できません。 _@MappedSuperclass
_アノテーションが付けられた基本クラスに対してそれを行います。
ここで、 _@Inheritance
_ JPAアノテーションを使用する理由は、Strategy Pattern のような動作駆動型パターンを実装するためです。
一方、_@MappedSuperclass
_は、共通の基本クラスを使用して、基本的なプロパティ、関連付け、およびエンティティ_@Id
_の両方を再利用する方法にすぎません。それでも、_@Embeddable
_型を使用してほぼ同じ目標を達成できます。唯一の大きな違いは、_@Id
_を使用して_@Embeddable
_定義を再利用できないことですが、_@MappedSuperclass
_を使用して再利用できます。