2

Eclipselink永続性プロバイダーをDB2DBで調整しています。定義を簡略化した3つの表を以下に示します。

CREATE TABLE root
(
    id       CHAR(32) NOT NULL PRIMARY KEY,
    rec_type VARCHAR(20)
);

CREATE TABLE derived
(
    id CHAR(32) NOT NULL PRIMARY KEY,
    ...
);
ALTER TABLE derived ADD CONSTRAINT fk_derived_to_root FOREIGN KEY (id) REFERENCES root(id);

CREATE TABLE secondary
(
    derived_id NOT NULL PRIMARY KEY,
    ...
);
ALTER TABLE secondary ADD CONSTRAINT fk_secondary_to_derived FOREIGN KEY (derived_id) REFERENCES derived(id);

これらのエンティティのJavaエンティティクラスを以下に示します。RootEntity:

@javax.persistence.Table(name = "ROOT")
@Entity
@DiscriminatorColumn(name = "REC_TYPE")
@Inheritance(strategy = InheritanceType.JOINED)
public class RootEntity {
    private String id;

    @javax.persistence.Column(name = "ID")
    @Id
    @GeneratedValue(generator = "system-uuid")
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    private String principalType;
    @Column(name = "PRINCIPAL_TYPE")
    public String getPrincipalType() {
        return principalType;
    }

    public void setPrincipalType(String principalType) {
        this.principalType = principalType;
    }
   ...
}

DerivedEntity:

@javax.persistence.Table(name = "DERIVED")
@Entity
@DescriminatorValue("DERIVED")
public class DerivedEntity extends RootEntity {
    private SecondaryEntity secondaryEntity;

    @OneToOne(mappedBy = "derived_id")
    public SecondaryEntity getSecondaryEntity() {
        return secondaryEntity;
    }

    public void setSecondaryEntity(SecondaryEntity secondaryEntity) {
        this.secondaryEntity = secondaryEntity;
    }
 ...
}

テストログに派生テーブルの挿入が表示されません。

--INSERT INTO ROOT (ID, REC_TYPE) VALUES (?, ?)
    bind => [241153d01c204ed79109ce658c066f4c, Derived]
--INSERT INTO SECONDARY (DERIVED_ID, ...) VALUES (?, ...)
    bind => [241153d01c204ed79109ce658c066f4c, ...]
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.ibm.db2.jcc.am.fo: DB2 SQL Error: SQLCODE=-530, SQLSTATE=23503, SQLERRMC=SCHEM.SECONDARY.FK_SECONDARY_TO_DERIVED, DRIVER=3.57.82

したがって、質問は、EclipselinkがDERIVEDテーブルに挿入する前に新しいレコードをテーブルに挿入しないのはなぜSECONDARYですか?

PSテーブルがない場合SECONDARYROOTおよびDERIVEDテーブルのみ)または継承が使用されていない場合(DERIVEDテーブルがIDを生成する場合)、すべてが正常に機能しています。

4

1 に答える 1

2

継承の場合、JPAは、関連テーブルの外部キー制約がルートテーブルを参照していると想定します。

ルートテーブルを参照するように制約を変更できます。または、

DescriptorCustomizerを使用して、

descriptor.setHasMultipleTableConstraintDependecy(true);

また、

カスタマイザOneToOneMappingは、外部キーがセカンダリテーブルを参照するようにします(JPAアノテーションは常にルートテーブルを参照するようにします)。

ただし、JPA結合列では、セカンダリテーブルへの外部キーを定義できるため、バグをログに記録してください。

EclipseLinkがセカンダリテーブルへの挿入を延期する理由は、挿入をテーブルごとにグループ化して、バッチ書き込みを可能にし、データベースのデッドロックを回避できるようにするためです。

于 2012-06-26T12:36:14.423 に答える