2012-03-12 26 views
42

私はPostgreSQLJPAでPlay Framework 1.2.4を使用しています。私はモデル階層を持ち、これを行うためのいくつかの選択肢があることを確認したいと思います。JPA:モデル階層の実装 - @MappedSuperclassと@Inheritance

私は基本クラス(抽象クラ​​ス)と、この基本クラスを拡張する2つの具象クラスを持っています。私は具体的なクラスを持っている間、この基本クラスを維持したくありません。基本クラスでは、プロパティとして別のModelクラスがあります。つまり、基本クラスに@ManyToOneという関係があります。

私の質問は、これを実装する最良の方法は何ですか? @MappedSuperclassまたは@InheritanceTABLE_PER_CLASS戦略を使用していますか?私はちょっと混乱しているようですが、とほぼ同じです。と同等です。

また、私が今後直面するかもしれないクエリやパフォーマンスの問題については、いくつか懸念があります。

+1

「@継承」を「@継承」に変更しました。 –

答えて

96

MappedSuperClassは、プロパティ、関連付け、およびメソッドを継承するために使用する必要があります。

エンティティと複数のサブエンティティがある場合は、エンティティの継承を使用する必要があります。

この質問に答えることで、どちらか一方が必要かどうかを知ることができます。モデルに、基本クラスと関連付ける可能性のある他のエンティティがありますか?

「はい」の場合、基本クラスは実際にはエンティティであり、エンティティの継承を使用する必要があります。そうでない場合、基本クラスは実際にはいくつかの無関係なエンティティに共通する属性とメソッドを含むクラスであり、マップされたスーパークラスを使用する必要があります。例えば

:SMSメッセージ、電子メールメッセージ、または電話メッセージ:

  • あなたはいくつかのメッセージの種類を持つことができます。そして人はメッセージのリストを持っています。メッセージの種類に関係なく、メッセージにリマインダーをリンクさせることもできます。この場合、Messageは明らかにエンティティであり、エンティティの継承を使用する必要があります。
  • すべてのドメインオブジェクトに作成日、変更日、IDが設定されている可能性があります。そのため、基本的なAbstractDomainObjectクラスから継承できます。しかし、どのエンティティも、AbstractDomainObjectへの関連を持つことはありません。常により特定のエンティティ(顧客、会社など)との関連になります。この場合、MappedSuperClassを使用するのが理にかなっています。
+0

あなたの答えに多くの感謝。私は今、私が永続化する必要があるか、またはエンティティとして基本クラスを使用する必要がある場合、私はエンティティ継承を使用する必要があることを明確にしています。特に継承されたオブジェクトリレーションを使用してクエリのパフォーマンスや制限に問題があるのだろうか? – huzeyfe

+0

それはあなたが選んだ継承の種類と継承戦略によって異なります。 –

+0

私の場合(基本クラスを永続化したくないので)、MappedSuperClassがより適しているようです。パフォーマンスと制限の点で、私はいくつかの特定の問題を認識する必要がありますか? – huzeyfe

2

this articleで説明したように、@MappedSupperclassは、@Inheritanceアノテーションとは異なります。

@MappedSuperclassは、それらが@MappedSuperclassでアノテートスーパークラスを拡張し、子クラスによって宣言されたかのように、基本クラスの永続プロパティを含めるようにJPAプロバイダに指示します。

しかし、データベースの観点から見ると、継承は基本クラスの表示がないため、継承はOOP世界でのみ表示されます。子クラスのエンティティのみが、関連するマップされたテーブルを持ちます。

@Inheritanceアノテーションは、データベーステーブル構造のOOP継承モデルを実現するためのものです。さらに、@Inheritanceでアノテーションされた基本クラスを照会することはできますが、@MappedSuperclassでアノテーションされた基本クラスに対しては実行できません。

ここで@Inheritance JPA annotation is to implement behavior-driven patterns like the Strategy Patternを使用する理由は次のとおりです。

一方、@MappedSuperclassは、共通の基本クラスを使用して基本プロパティ、関連付け、さらにはエンティティ@Idの両方を再利用するための単なる方法です。それにもかかわらず、@Embeddableタイプを使用してほぼ同じ目標を達成できます。唯一の大きな違いは、@Idの定義を@Embeddableと再利用することはできませんが、@MappedSuperclassで行うことができます。