0

単方向ツリーを持つ DB テーブルがあります。これらの木の葉は、複数の子/親を持つことができます。サイクルは制限されています。これが私のDBテーブルの定義です:

CREATE MULTISET TABLE WORKFLOW_SEQ_REL ,NO FALLBACK ,
     NO BEFORE JOURNAL,
     NO AFTER JOURNAL,
     CHECKSUM = DEFAULT,
     DEFAULT MERGEBLOCKRATIO
     (
      WORKFLOW_SEQ_ID INTEGER NOT NULL,
      REL_WORKFLOW_SEQ_ID INTEGER NOT NULL,
      JOB_ID BIGINT)
PRIMARY INDEX ( WORKFLOW_SEQ_ID );

ご覧のとおり、現在は主キーがありません。しかし、後で表示されます :) 実際の PK は、JOB_ID+PARENT_ID+CHILD_ID です。

アイデアは次のとおりです。

  1. REL_WORKFLOW_SEQ_ID = 親
  2. WORKFLOW_SEQ_ID = 子
  3. JOB_ID = TREE_IDENTIFICATOR (1 つのテーブルに格納された異なるツリーを分離する決定要因)。

JPAエンティティを宣言しようとしています:

@Entity
@Table(name="WORKFLOW_SEQ_REL")
public class EtlWorkflowSeqNode {


    @EmbeddedId 
    public EtlWorkflowSeqNodeId etlWorkflowSeqNodeId;

    //@Column(name="JOB_ID")
    //public Integer jobId;

    @Embeddable
    class EtlWorkflowSeqNodeId{

        @Column(name="JOB_ID")
        public Integer jobId;


        @ManyToOne(fetch = FetchType.EAGER)
        @JoinColumn(name="REL_WORKFLOW_SEQ_ID")
            //EtlWorkflowSeq.id = PK of EtlWorkflowSeq entity
        public EtlWorkflowSeq parent;

        @OneToMany(fetch=FetchType.EAGER /*, mappedBy="parent"*/)
        @JoinColumn(name="WORKFLOW_SEQ_ID")
        public Set<EtlWorkflowSeq> children;
    }
}

エラーが発生しました: 原因: org.hibernate.AnnotationException: A Foreign key refering models.EtlWorkflowSeqNode from models.EtlWorkflowSeq has the wrong number of column. 2である必要があります

EtlWorkflowSeq エンティティは次のとおりです。

@Entity
@Table(name="WORKFLOW_SEQ")
public class EtlWorkflowSeq {

    @Id
    @Column(name="WORKFLOW_SEQ_ID")
    public Integer id;

    @OneToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="WORKFLOW_ID")
    public EtlWorkflow etlWorkflow;
}

私は何を間違っていますか?

UPD: テーブル定義は次のとおりです: -- 悪い設計です。PK は次のようになります: WORKFLOW_SEQ_ID + REL_WORKFLOW_SEQ_ID + JOB_ID

 CREATE MULTISET TABLE WORKFLOW_SEQ_REL ,NO FALLBACK ,
         NO BEFORE JOURNAL,
         NO AFTER JOURNAL,
         CHECKSUM = DEFAULT,
         DEFAULT MERGEBLOCKRATIO
         (
          WORKFLOW_SEQ_ID INTEGER NOT NULL, --a ref to child
          REL_WORKFLOW_SEQ_ID INTEGER NOT NULL, -- a ref to parent
          START_TYPE_ID SMALLINT NOT NULL, -- a type of connection
          DISABLE_START_TYPE_ID SMALLINT, -- other type of connection
          JOB_ID BIGINT) -- a tree determinant, 
    PRIMARY INDEX ( WORKFLOW_SEQ_ID );

    CREATE MULTISET TABLE   WORKFLOW_SEQ ,NO FALLBACK ,
         NO BEFORE JOURNAL,
         NO AFTER JOURNAL,
         CHECKSUM = DEFAULT,
         DEFAULT MERGEBLOCKRATIO
         (
          WORKFLOW_SEQ_ID INTEGER NOT NULL, -- an id
          WORKFLOW_ID BIGINT NOT NULL, -- a ref to original workflow, not interesting
          IS_NAME VARCHAR(255) CHARACTER SET UNICODE NOT CASESPECIFIC, -- some name
          INFO_SYSTEM_INST_CD VARCHAR(255) CHARACTER SET UNICODE NOT CASESPECIFIC, -- other name
          DISABLE BYTEINT) -- so garbage
    UNIQUE PRIMARY INDEX ( WORKFLOW_SEQ_ID ); -- it should also be a PK

複数のツリーが WORKFLOW_SEQ_REL JOB_ID に格納されているという考えは、ツリーの決定要因です。WORKFLOW_SEQ_ID、REL_WORKFLOW_SEQ_ID は、REL_WORKFLOW_SEQ テーブルからカスタマイズされたテンプレートを参照します。

4

1 に答える 1

1

あなたの質問には矛盾があることに気が付かずにはいられません。

あなたは最初に次のように述べています。

これらの木の葉は、複数の子/親を持つことができます。

これにより、リーフ間の関係が多対多になると私は信じています。

葉を表すあなたの質問を作成すると、オブジェクト間の関係を表すEtlWorkflowSeqと思いますか?EtlWorkflowSeqNodeEtlWorkflowSeq

ただし、ノードは1 つの親と多くの子を指します。

次のようなものを使用して、同様のものを作成できます。

@Entity
@Table(name="WORKFLOW_SEQ")
public class EtlWorkflowSeq
{
    @Id
    @GeneratedValue
    @Column(name="WORKFLOW_SEQ_ID")
    public Integer id;

    @ManyToOne
    @JoinColumn(name="WORKFLOW_ID")
    public EtlWorkflow etlWorkflow;

    @ManyToMany
    @JoinTable(name = "WORKFLOW_SEQ_REL")
    private Set<EtlWorkflowSeq> children;

    @ManyToMany(mappedBy = "children")
    private Set<EtlWorkflowSeq> parents;

    @ManyToOne
    @JoinColumn(name = "JOB_ID", referencedColumnName = "id")
    private Job job;
}

これは時代遅れEtlWorkflowSeqNodeになります。EtlWorkflowSeqNodeId

@Embeddableまた、を使用する場合は、基本型のみを使用する必要があることも述べたいと思います。基本型以外を使用することはできません/問題が発生します/標準ではありません (間違っている場合は修正してください)。

複合主キーで外部キーを使用したい場合は、これを使用できます。

@Entity
public class Foo
{
    @Id
    private Long id;
}

@Entity
public class Bar
{
    @EmbeddedId
    private BarPK key;

    @MapsId(value = "fooId")
    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "foo_id", referencedColumnName = "id")
    })
    private Foo foo;
}

@Embeddable
public class BarPK
{
    @Column(name = "id")
    private Long id;

    @Column(name = "foo_id")
    private Long fooId;
}
于 2012-06-07T08:07:34.060 に答える