0

以下の例を考えてみましょう。

フルーツ、オレンジ、アップルの3つのテーブルがあります

idはフルーツテーブルで生成され、ここで主キーになります

idはOrangeとAppleの主キーでもあります(共有主キー)

たとえば、フルーツのidが1、2、3、4、5の場合、シナリオは1、2はオレンジ、3、4はアップル、5は再びオレンジになります。

したがって、オレンジのテーブルのIDは1、2、5になり、アップルのテーブルのIDは3、4になります。

=================================== 
 Fruit
===================================
 id     |   shape
===================================
  1     |   round
  2     |   round
  3     |   oblong
  4     |   oblong
  5     |   round
===================================


===================================
 Orange
===================================
 id     |   color    | taste
===================================
  1     |   orange   |  sour
  2     |   orange   |  sour
  5     |   orange   |  sour
===================================


===================================
 Apple
===================================
 id     |   density    | weight
===================================
  1     |   hard       |  200
  2     |   hard       |  220
  5     |   hard       |  230
===================================

問題:JPAアノテーションのみとの関係をキャプチャするエンティティクラスを作成する方法(休止状態のgeneratedValueアノテーションを使用したくない)。

そのような注釈が純粋なJPAで可能である場合は、それに向けて私を案内してください。

ニック

4

2 に答える 2

2

あなたのケースは、「Generalization Specialization」、または略してGen-Specとして知られているデザインパターンのインスタンスのように見えます。データベーステーブルを使用してgen-specをモデル化する方法の問題は、SOで常に発生します。

JavaなどのOOPLでgen-specをモデル化する場合は、サブクラス継承機能を使用して詳細を処理します。一般化されたオブジェクトを処理するクラスを定義してから、特殊なオブジェクトのタイプごとに1つずつ、サブクラスのコレクションを定義するだけです。各サブクラスは、一般化されたクラスを拡張します。それは簡単で簡単です。

残念ながら、リレーショナルデータモデルにはサブクラスの継承が組み込まれておらず、SQLデータベースシステムにはそのような機能はありません。しかし、あなたは運が悪いわけではありません。OOPのクラス構造に対応する方法で、gen-specをモデル化するようにテーブルを設計できます。次に、一般化されたクラスに新しいアイテムが追加されたときに、独自の継承メカニズムを実装するように調整する必要があります。詳細は以下の通りです。

クラス構造はかなり単純で、genクラス用に1つのテーブル、specサブクラスごとに1つのテーブルがあります。これは、マーティンファウラーのウェブサイトからの素敵なイラストです。 クラステーブル継承。この図では、Cricketerはサブクラスとスーパークラスの両方であることに注意してください。どの属性をどのテーブルに入れるかを選択する必要があります。この図は、各テーブルの1つのサンプル属性を示しています。

トリッキーな詳細は、これらのテーブルの主キーをどのように定義するかです。genクラステーブルは通常の方法で主キーを取得します(このテーブルがクリケット選手のようなさらに別の一般化の特殊化である場合を除く)。ほとんどの設計者は、主キーに「Id」などの標準名を付けます。自動番号機能を使用して、Idフィールドに入力します。スペッククラステーブルは「Id」という名前の主キーを取得しますが、自動番号機能は使用されません。代わりに、各サブクラステーブルの主キーは、一般化されたテーブルの主キーを参照するように制約されます。これにより、特殊な主キーのそれぞれが、主キーだけでなく外部キーにもなります。クリケット選手の場合、IdフィールドはプレーヤーのIdフィールドを参照しますが、ボウラーのIdフィールドはクリケット選手のIdフィールドを参照することに注意してください。

これで、新しいアイテムを追加するときに、参照整合性を維持する必要があります。方法は次のとおりです。
最初に新しい行をgenテーブルに挿入し、主キーを除くすべての属性のデータを提供します。自動番号メカニズムは、一意の主キーを生成します。次に、主キーを含むすべての属性のデータを含む、新しい行を適切なスペックテーブルに挿入します。使用する主キーは、生成されたばかりの新しい主キーのコピーです。この主キーの伝播は、「貧乏人の相続」と呼ぶことができます。

これで、すべての一般化されたデータと1つのサブクラスからのすべての特殊化されたデータが必要な場合、必要なのは、共通のキーを介して2つのテーブルを結合することだけです。問題のサブクラスに関係しないすべてのデータは、結合から除外されます。それは滑らかで、簡単で、そして速いです。

gen-specパターンを実装するSQLテーブルの設計は、少し注意が必要な場合があります。データベース設計のチュートリアルでは、このトピックについてよく説明します。しかし、実際には何度も何度も出てきます。

「一般化スペシャライゼーションリレーショナルモデリング」でWebを検索すると、これを行う方法を説明するいくつかの役立つ記事が見つかります。また、このフォーラムでこのトピックが以前に取り上げられたことも何度か指摘されます。

記事では通常、すべての一般化されたデータをキャプチャする単一のテーブルと、そのサブクラスに固有のすべてのデータを含むサブクラスごとに1つの特殊なテーブルを設計する方法を示します。興味深い部分には、サブクラステーブルの主キーが含まれます。サブクラスの主キーを設定するためにDBMSの自動番号機能を使用することはありません。代わりに、一般化されたテーブルに対して取得された主キー値を適切なサブクラステーブルに伝播するようにアプリケーションをプログラムします。

これにより、一般化されたデータと特殊化されたデータの間に双方向の関連付けが作成されます。各特殊なサブクラスの単純なビューは、一般化された特殊なデータを一緒に収集します。一度コツをつかめば簡単で、かなりうまく機能します。

于 2012-07-31T10:07:24.817 に答える
0

2つのJavaフィールド(idとassociation)を同じ列にマップするように強制することによってテストされます。

例えば、

class Orange {

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


   @OneToOne
   @JoinColumn(name="id")
   Fruit fruit;

   public Orange(Fruit fruit) {
      this.fruit = fruit;
      this.id = fruit.id;
   }

   protected Orange() { } // default constructor required by JPA
}

しかし、JPAプロバイダーがどのように動作するかはわかりません。

于 2011-10-05T12:10:04.330 に答える