1

そのため、私はJPAの継承機能に慣れるために取り組んでおり、これまでのところ非常に気に入っています。最近私が思いついたのは、データを取得する以外の目的で実際に使用できるということです。識別子の値に基づいてサブクラスを取得できることを考えると、継承は実際には構成フィールドを実装に変換するための便利な方法です。私の知識と経験の比率が「危険である/常にそれを実現するのに十分ではない」という段階にあるので、これが良い考えであるかどうかを尋ねるのが最善かもしれないと思いました。

この例では、PRODUCTテーブルとBILLTYPEテーブルを使用します。

Product:
int Id
int billtypeid

Billtype:
int id
varchar[15] description

Billtypeは、単に製品の請求戦略です(一部の注文は重量で請求される場合もあれば、ケースごとに請求される場合もあります)。請求書の種類ごとに、請求プロセス中にさまざまな方法を使用する必要があります。Billtypeテーブルには、ほんの一握りのエントリしかない可能性があり、非常に大きくなることはありません。

継承を使用して、請求書コードに必要なさまざまなメソッドのインターフェイスも定義する抽象Billtypeエンティティをサブクラス化することは理にかなっていますか?このようなもの:

@Entity
@DiscriminatorColumn("description")
public abstract class BillType {
   // Getters, setters
   // Abstract methods that could be used elsewhere - ex:
   // BigDecimal calculateInvVal(...)
}


@Entity
@DiscriminatorValue("by case")
public class CaseBillType extends BillType {
   // Implementation of calculateInvVal - now when invoicing code needs this method, 
   // the right one is always associated with the current product!
}

これは、動作を構成データを表すデータベース内のフィールドに関連付ける便利な方法を提供しますが、ビジネスコードをエンティティと混合します(ほとんどのアカウントでは、これは非常にいたずらです)。この問題を修正するためのデザインパターンがあり、レパートリーから欠落している可能性がありますが、「請求書の種類がこれである場合、このサブクラスを取得する、請求書の種類がこれである場合など」をたくさん書く必要はありません。 "コード。

私が答えから探しているのは、この問題の別の解決策を探すことを正当化する、この手法の潜在的な欠点の説明です。

4

1 に答える 1

2

新しいバージョンのアプリケーションを再構築および再デプロイする必要なしに、実行時に請求書タイプを追加、削除、および変更できる場合は、製品をBillTypeエンティティにリンクすると便利です。これはあなたの例には当てはまりません。

したがって、請求書タイプの静的セットがあり、それぞれがBillTypeサブクラスによってカプセル化された静的動作を定義している場合は、代わりにBillType列挙型を使用できます。この列挙型の各インスタンスは、独自の動作を定義します。このためにエンティティ階層と追加のテーブルは必要ありません。

ProductエンティティでInValを計算するコードは、まったく同じです。

BigDecimal computeInVal() {
    billType.calculateInVal(this);
}

すべての請求書タイプを取得するためのコードは次のようになります

return BillType.values();

そして、請求書タイプを製品に関連付けるための次のコードの代わりに:

product.setBillType(em.find(BillType.class, ID_OF_CASE_BILL_TYPE));

あなたは単に持っているでしょう

product.setBillType(BillType.BY_CASE);
于 2012-04-17T14:12:09.220 に答える