3

こんにちは私はJPAを初めて使用し、JPAが継承をどのように処理するかを理解するのに苦労しています。

DBスキームを変更せずに解決する必要がある特定の問題がありますが、解決策が見つからない場合は、別のDBスキームを使用した解決策の提案をいただければ幸いです(Hibernate / TopLinkソリューションを歓迎します)。

不明な点がある場合、または詳細が必要な場合は、その旨を教えてください。前もって感謝します!

私はこのデータベースを持っています:

TABLE Fruit
Id Varchar (10) Primary Key
size Varchar (10)
fruit_type Varchar(10)

TABLE Apple
Id Varchar (10) Primary Key Foreign Key references Fruit.Id
Apple_Property Varchar(10)

これまでのところ、私のエンティティは次のようになっています。

@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="fruit_type", discriminatorType=DiscriminatorType.Char)
@DiscriminatorValue(value="fruit")

public class Fruit implements Serializable {

    @Id
    protected String Id;

    protected String size;
}

@Entity
@DiscriminatorValue(value="apple")
//@PrimaryKeyJoinColumn(name="Id" , referencedColumnName="Id")

public class Apple extends Fruit implements Serializable {

    private String Apple_Property;
}

現在、Fruitオブジェクトを問題なく永続化できます。Appleオブジェクトは、Fruitオブジェクトがまだ永続化されていない場合にのみ永続化されます。

すでに永続化されているFruitオブジェクトを使用してAppleオブジェクトを永続化しようとすると:

Fruit fruit1 = new Fruit("1", "Small");
Apple apple1 = new Apple(fruit1, "red");
provider.create(fruit1);
provider.create(apple1);

JPAがすでに存在するId="1"でFruitテーブルに新しい行を作成しようとするため、エラーが発生します。

..

4

4 に答える 4

3

JPAを使用して子オブジェクトを永続化する場合(つまりprovider.create(apple1)、あなたの場合)、子テーブルとそのすべての親テーブルにレコードが挿入されます。したがってprovider.create(apple1)、レコードを Fruit に挿入し、レコードを Apple テーブルに挿入します。

あなたの例では、リンゴオブジェクトのみを永続化したい場合は、呼び出すだけprovider.create(apple1)で十分です。リンゴ オブジェクト内の果物の参照も永続化されます。

ところで、私は Fruit Table の PK を数値型にすることを提案し@GeneratedValue、Fruit Bean の ID フィールドをマークするために使用します。このようにして、データベースにIDを生成させることができ、Javaコードで既存のIDを設定するため、この「IDはすでに存在するエラー」を回避するためにJavaコードで明示的に設定する必要がなくなります。

于 2011-05-07T08:49:27.687 に答える
1

これは設計どおりに機能していると思います。結合された継承を使用してアップルオブジェクトを永続化すると、JPAはアップルテーブルとフルーツテーブルの両方に自動的に挿入されます。エンティティクラスで追加のリレーションやJoinColumnをモデル化する必要はありません。

于 2011-05-07T07:53:41.240 に答える
0

dbテーブルの作成中にJava継承の概念を使用しようとしていますが、この場合は不可能です。この問題に対する1つの異なるアプローチを考えることができます。テーブルfruit_typeとfruitがあります。Fruit_type(id、typename、desc)fruit(id、name、type_id、desc)ここでtype_idは外部キーになります。

于 2011-05-07T04:24:58.653 に答える
0

私は同じ問題を抱えていますが、これまでに見つけた唯一の方法は、親にクエリを実行し、親で子を構築することでした。次に、親を削除して、両方のレコードを再作成します。

于 2016-06-21T22:56:30.187 に答える