web-dev-qa-db-ja.com

JPA(+ Hibernate)で継承された抽象クラス

次のコード例では、注釈をどのように構成しますか? JPAアノテーションのみに固執し、Hibernate固有の依存関係を回避したいと思います。 以下のコードは正しいですか?

@Entity
public class RefExample extends RefData {

}

(これらのクラスの複数のバージョン、RefSomeOtherExampleなど、およびクラスごとに1つのdbテーブルがあります。一部は追加のフィールド(列)を追加できますが、ほとんどは「RefData」基本クラスから継承した基本フィールドを使用します)

基本クラス:

@Entity
public abstract class RefData {

    private long id;
    private String code;
    private String desc;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    public long getId() {

        return id;
    }

    public void setId(long id) {

        this.id = id;
    }

    @Column(unique = true, nullable = false, length=8)
    public String getCode() {

        return code;
    }

    public void setCode(String code) {

        this.code = code;
    }

    @Column(unique = true, nullable = false, length=80)
    public String getDesc() {

        return desc;
    }

    public void setDesc(String desc) {

        this.desc = desc;
    }
}

最終的には、HibernateのSchemaExportクラスを使用して、これからスキーマ作成スクリプトを生成したいと思います。上記の場合、これらの2つのクラスは、「RefData」の3つの列を持つ「RefExample」という名前の単一のテーブルを作成するだけです。これは機能しますか?

41
Manius

JPA 1.0仕様から:

抽象クラスと具象クラスの両方をエンティティにすることができます。 抽象クラスと具象クラスの両方にEntityアノテーションを付けることができます、エンティティとしてマップされ、エンティティとして照会されます。

エンティティは非エンティティクラスを拡張でき、非エンティティクラスはエンティティクラスを拡張できます

単一のテーブルが必要な場合は、 Single Table inheritanceを使用する必要があります。

次のように弁別子列を定義するだけです。

@Entity
@DiscriminatorColumn(name="REF_TYPE")
public abstract class RefData {

ただし、JPA継承戦略に依存したくない場合は、代わりにMappedSuperclassを使用できます。

@MappedSuperclass
public abstract class RefData {

JPA仕様

エンティティは、永続的なエンティティの状態とマッピング情報を提供するスーパークラスから継承できますが、それ自体はエンティティではありません。通常、このようなマッピングされたスーパークラスの目的複数のエンティティクラスに共通の状態およびマッピング情報を定義する

できません @Entityと@MappedSuperclassを同時に使用してください。

88
Arthur Ronald

@ MappedSuperclassは私のために働いています。ビューを親クラスと子クラスである2つのオブジェクトにマップするのに苦労しました。私のビューは2つのテーブルから結合されています。ビューには両方のテーブルの主キーが存在します。 @ DiscriminatorColumnは、オブジェクトのデータ型に排他的に割り当てられた列を必要とし、'repeated Column in object exception'私は解決できませんでした。

このフォーラムを読んで、@ MappedSuperclassアノテーションを試しました。トリックを行います。

@ MappedSuperclassをスーパークラスに入れ、@ Id@ GeneratedValueをスーパークラス識別子に入れました。私が与えたサブラスで

@Entity
@Table(name="view_name")

そして、サブクラスオブジェクトを使用して、ビューからデータを取得しました。それでおしまい。

@ DiscriminatorColumnを使用せずに結合テーブルの休止状態アノテーションの継承が機能しました。

5
Amirtharaj

これには、継承戦略の1つを使用できます。あなたのケースは、階層の単一クラスのケースのようです。

チェック this

0
lalit