[英]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.