0

我确实有一个带有单向树的数据库表。这些树的叶子可以有几个孩子/父母。周期受到限制。这是我的数据库表定义:

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(用于分隔存储在一个表中的不同树的决定因素)。

我正在尝试声明一个 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:引用 models.EtlWorkflowSeqNode 的外键来自 models.EtlWorkflowSeq 的列数错误。应该是 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代表叶子的问题时,我认为EtlWorkflowSeqNode代表对象之间的关系EtlWorkflowSeq

但是,节点指向一个父节点和多个子节点。

你可以使用这样的东西来创建类似的东西:

@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

我还想声明,在使用 an 时,@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 回答