web-dev-qa-db-ja.com

同じビジネスオブジェクトを参照する複数のテーブルを持つJPAエンティティのクラス設計

さまざまな外部データソース(DataSourceProduct内)の製品と連携するアプリケーションがあり、それは(MasterProduct内の)製品の独自のバージョンも維持しています。 DBスキーマは次のとおりです。

DB Schema

注:DataSourceProductには、図に示されていない他の10列があります。 MasterProductには、図に示されていない他の10列があります。たとえば、これらの列は各テーブルで同じ名前です。同じ名前ですが、簡潔にするために、図には示されていません。共通の列はProductテーブルではなく、DataSourceProductにあります

各外部データソースは、特定の製品の独自の表現を提供します。 productId(つまり、Product.id)は、データベースで自動生成(増分)するIDです。これは代理キーです。 productIdは1つの実世界の製品のみを参照する必要があります。各データソースにはその製品に関する独自のデータがあり、DBはそれをキャプチャする必要があります。鉄製のドアがあるとします。それがDBに挿入された最初の製品である場合、productIdは1になります。今度は、データソースAが「ファインドア」の説明を提供します。データソースBは、同じアイアンドアに「古いアイアンドア」の説明を与える場合があります。したがって、DataSourceProductには2行(データソースごとに1行)があります。両方の行のproductId = 1になるので、両方のデータソースが実際に同じ製品を参照していることがわかります。

残念ながら、データソースAとデータソースBの製品が同じ製品を参照していると判断できるデータ(SKUなど)はありません。ユーザーは手動で製品を同じものとしてマップします。 ProductテーブルのproductIdは、ユーザーマッピング(つまり、さまざまなデータソースのどの製品が同じ製品を参照しているか)を格納する目的で使用されます。

また、アプリケーションには、MasterProductテーブルに格納される独自のバージョンの製品データが必要です。 DataSourceProductと異なるのは、

  1. 製品へのデータ変更の履歴を維持する必要がある
  2. ベンダーデータを維持する必要がある

アプリケーションの製品(MasterProduct)はアプリケーション全体で広く使用されますが、外部データソースの製品(DataSourceProduct)はアプリケーションの1つの小さな部分でのみ使用されます。

対応するJPAエンティティをどのように設計すればよいですか?製品を表す3つのテーブルは、DBの観点からは(?) OOPでも、継承関係が存在するようです。

1
James

ID以外は何も含まれていないため、混乱はProductテーブルの一般的なユーティリティの欠如に起因すると思います。

しかし、それは大したことではありません。 JPAエンティティを定義するときは、Productsテーブルから始めて、各子オブジェクトを個別のクラスとして定義します。次に、それらをProductクラスに含めます。

@Entity
@Table(name = "PRODUCT")
public class Product {

   @Id
   @Column(name = "id")
   private long id;

   @OneToMany(mappedBy="product")
   List<DataSourceProduct> dataSourceProducts;

   @OneToMany(mappedBy="product")
   List<MasterProduct> masterProducts;
}

これらの子製品のそれぞれは、Productテーブルとの逆の@ManyToOne関係で定義されます。

コメントで述べたように、これらの名前を変更して、一部のプロパティを移動することもできますが、この構造は出発点として適していると思います。

1
Andrew