1

ここここの回答にリンクされている多数の応答とさまざまな Hibernate オープン JIRA チケットは すべて、 (以下に示すように) andを使用してInheritanceType.JOINED戦略を使用しようとしてもうまくいかないことを示しています。具体的には、https://hibernate.onjira.com/browse/HHH-6911を参照してください。@DiscriminatorColumn@DiscriminatorValue

私のシナリオは、標準の「型」テーブルを使用して抽象型の具体的な型の数を区別し、参照整合性制約によって整列を強制するレガシーデータベースを持っているというものです。JPAモデルがデータベースモデルの意図を忠実に表現するには、抽象型の Discriminator フィールドを正しく設定する必要があるようです。表の簡略版は次のとおりです。

CREATE TABLE CONTACT_INFORMATION (
    CONTACT_INFORMATION_ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    FK_STND_CONTACT_INFO_TYPE_ID INTEGER UNSIGNED NOT NULL,
    -- more here...
    PRIMARY KEY (CONTACT_INFORMATION_ID)
);

CREATE TABLE STND_CONTACT_INFO_TYPE (
    STND_CONTACT_INFO_TYPE_ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
    CONTACT_INFO_TYPE_CD CHAR(5) NOT NULL,
    DESCRIPTION_TX VARCHAR(30),
    PRIMARY KEY (STND_CONTACT_INFO_TYPE_ID)
);

CREATE TABLE POSTAL_ADDRESS (
    FK_CONTACT_INFORMATION_ID INTEGER UNSIGNED NOT NULL,
    -- more here...
    PRIMARY KEY (FK_CONTACT_INFORMATION_ID)
);

CREATE TABLE ELECTRONIC_ADDRESS (
    FK_CONTACT_INFORMATION_ID INTEGER UNSIGNED NOT NULL,
    -- more here...
    PRIMARY KEY (FK_CONTACT_INFORMATION_ID)
);

ELECTRONIC_ADDRESSからとPOSTAL_ADDRESSまでCONTACT_INFORMATION、およびからCONTACT_INFORMATIONまでの参照整合性制約がありますSTND_CONTACT_INFORMATION_TYPE

このモデルで作業できる JPA アノテーション付きエンティティを作成しようとして、次のことを思いつきました。

@Entity
@Table(name = "CONTACT_INFORMATION")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "FK_STND_CONTACT_INFO_TYPE_ID", discriminatorType = DiscriminatorType.INTEGER)
public abstract class ContactInformation {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "CONTACT_INFORMATION_ID", unique = true, nullable = false)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "FK_STND_CONTACT_INFO_TYPE_ID", nullable = false)
    private StandardContractInformationType contactInformationType;
}

@Entity
@Table(name = "STND_CONTACT_INFO_TYPE")
public class StandardContractInformationType  {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "STND_CONTACT_INFO_TYPE_ID", unique = true, nullable = false)
    private Integer id;

    @Column(name = "CONTACT_INFO_TYPE_CD", nullable = false)
    private String typeCode;

    @Column(name = "DESCRIPTION_TX", length = 30)
    private String description;
}

@Entity
@Table(name = "POSTAL_ADDRESS")
@PrimaryKeyJoinColumn(name = "FK_CONTACT_INFORMATION_ID")
@DiscriminatorValue(value = "1")
public class PostalAddress extends ContactInformation { /*...*/ }

@Entity
@Table(name = "ELECTRONIC_ADDRESS")
@PrimaryKeyJoinColumn(name = "FK_CONTACT_INFORMATION_ID")
@DiscriminatorValue(value = "2")
public class ElectronicAddress extends ContactInformation { /*...*/ }

この実装でもSTND_CONTACT_INFO_TYPE、2 つのサブタイプのテーブルに事前に読み込まれた参照データに対応する '1' と '2' の識別子の値をハードコーディングする必要があることに注意してください。

この実装で Hibernate 4 を使用すると、PostalAddress または ElectronicAddress のレコードを挿入しても、抽象ベース テーブルの FK_STND_CONTACT_INFO_TYPE_ID フィールドが正しく設定されません。

結局のところ、問題は次のとおりです。元のデータベース モデルの意図に忠実でありながら、適切な JPA モデルを操作し続けるために利用できるオプションは何ですか? 別のプロバイダーを試しますか?標準タイプ情報のルックアップを行い、リポジトリまたはサービス レイヤーに強制を追加しますか? 一生懸命目を細めてみて、これを継承の問題ではなく構成の問題として見てみませんか?

4

0 に答える 0