簡體   English   中英

hibernate composite主鍵包含一個復合外鍵,如何映射這個

[英]hibernate composite Primary key contains a composite foreign key, how to map this

我在那里搜索,沒有找到任何類似的話題,所以我發布了一個新問題。

我正在使用現有數據庫上的Hibernate。 我們不允許更改表結構和數據。 應用程序正在從數據庫中讀取數據,並根據某些邏輯遷移到另一個數據存儲區。

現在問題是關於復合PK映射。 例如

表A具有復合PK。

Table A
--------
a1 (pk)
a2 (pk)
a3 (pk)
a4 (pk)
foo
bar
========

表B也具有復合PK,並且該復合PK的一部分是A的PK,這里也用作FK。

Table B
--------
a1 (fk,pk)
a2 (fk,pk)
a3 (fk,pk)
a4 (fk,pk)
b1 (pk)
b2 (pk)
b3 (pk)
foo
bar
========

我嘗試了幾種方法,但沒有一種方法可行。 誰能告訴一個有效的Hibernate映射解決方案? 注釋風格更好。

在B的pk類中將A的實體對象設置為@ManyToOne。

所以,如果你有

Class A
Class APK - A's Primary Key

Class B
Class BPK - B's primary Key.

BPK將包含A作為屬性

@Embeddable
public class BPK implements serializable {
  ....
  private A a;

  @ManyToOne(fetch=FetchType.EAGER)
  @JoinColumns ({
    @JoinColumn(name="...", referencedColumnName = "..."),
    @JoinColumn(name="...", referencedColumnName = "..."),
    ...
  })
  public getA() {
    return this.a;
  }
}

文檔中

@Embeddable繼承其擁有實體的訪問類型,除非使用Hibernate特定注釋@AccessType。 復合外鍵(如果不使用默認敏感值)是在使用@JoinColumns元素的關聯上定義的,該元素基本上是@JoinColumn的數組。 明確表達referencedColumnNames是一種很好的做法。 否則,Hibernate將假設您使用與主鍵聲明中相同的列順序。

如果復合主鍵只有代理鍵,請使用@EmbeddableId

@Embeddable
public class CompoundIdA implements Serializable {

    private Integer field0;
    private Integer field1;
    private Integer field2;
    private Integer field3;

    @Column(name="FIELD_0")
    public Integer getField0() {
        return this.field0;
    }

    @Column(name="FIELD_1")
    public Integer getField1() {
        return this.field1;
    }

    @Column(name="FIELD_2")
    public Integer getField2() {
        return this.field2;
    }

    @Column(name="FIELD_3")
    public Integer getField3() {
        return this.field3;
    }

    public boolean equals(Object o) {
        if(o == null)
            return false;

        if(!(o instanceof CompoundIdA))
            return false;

        final CompoundIdA other = (CompoundIdA) o;
        if(!(getField0().equals(other.getField0()))
            return false;

        if(!(getField1().equals(other.getField1()))
            return false;

        if(!(getField2().equals(other.getField2()))
            return false;

        if(!(getField2().equals(other.getField2()))
            return false;

        return true;
    }

    // hashcode impl

}

在ClassA中,我們有

@Entity
public class ClassA {

    private CompoundIdA compoundIdA;

    @EmbeddedId
    public CompoundIdA getCompoundIdA() {
        return this.CompoundIdA;
    }

}

如果復合主鍵同時具有自然鍵和代理鍵 ,請再次使用@EmbeddableId

// Let's suppose field0 and field1 are both natural keys
@Entity
public class ClassA {

    private CompoundIdA compoundIdA;

    private Integer field0;
    private Integer field1;

    @EmbeddedId
    public CompoundIdA getCompoundIdA() {
        return this.CompoundIdA;
    }

    @Column(name="FIELD_0", insertable=false, updateable=false)
    public Integer getField0() {
        return this.field0;
    }

    @Column(name="FIELD_1", insertable=false, updateable=false)
    public Integer getField1() {
        return this.field1;
    }

}

請注意, 您必須設置insertable = false和updateable = false,因為多個屬性共享同一列。 否則,Hibernate會抱怨一些錯誤。

如果復合主鍵只有自然鍵,請使用@IdClass

@Entity
@IdClass(CompoundIdA.class)
public class ClassA {

    private Integer field0;
    private Integer field1;
    private Integer field2;
    private Integer field3;

    @Id
    @Column(name="FIELD_0")
    public Integer getField0() {
        return this.field0;
    }

    @Id
    @Column(name="FIELD_1")
    public Integer getField1() {
        return this.field1;
    }

    @Id
    @Column(name="FIELD_2")
    public Integer getField2() {
        return this.field2;
    }

    @Id
    @Column(name="FIELD_3")
    public Integer getField3() {
        return this.field3;
    }

}

在ClassB中,您可以使用與上面所示相同的方法, 但是如果要定義@ManyToOne屬性, 則必須設置 insertable = false和updateable = false,如下所示

@Entity
public class ClassB {

    private ClassA classA;

    @ManyToOne
    @JoinColumns ({
        @JoinColumn(name="FIELD_0", referencedColumnName="FIELD_0", insertable=false, updateable=false),
        @JoinColumn(name="FIELD_1", referencedColumnName="FIELD_1", insertable=false, updateable=false),
        @JoinColumn(name="FIELD_2", referencedColumnName="FIELD_2", insertable=false, updateable=false),
        @JoinColumn(name="FIELD_3", referencedColumnName="FIELD_3", insertable=false, updateable=false)
    })
    public ClassA getClassA() {
        return this.classA;
    }

}

問候,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM