2017-07-31 167 views
0

我有一個類似的問題如下,但解決方案並沒有解決我的問題。休眠 - 複合主鍵包含外鍵

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

我試圖加入2個表,每一個具有與部分外鍵引用的複合主鍵。

Table A 
-------- 
f1 (pk) 
f2 (pk) 
f3 (pk) 
f4 (pk) 

Table B 
-------- 
f1 (pk, fk) 
f2 (pk, fk) 
f5 (pk) 
f6 (pk) 

I created A, APK, B, BPK 

在答:

private Set<B> bSet; 
@OneToMany(targetEntity=B.class, cascade = CascadeType.ALL, mappedBy= "bpk.a")  
public Set<MovesEntity> getBSet() { 
    return bSet; 
} 

在BPK:

@ManyToOne(fetch=FetchType.EAGER) 
@JoinColumns({ 
    @JoinColumn(name="f1", referencedColumnName="f1", nullable=false, insertable=false, updatable = false), 
    @JoinColumn(name="f2", referencedColumnName="f2", nullable=false, insertable=false, updatable = false) 
}) 
public A getA() { 
    return a; 
} 

上述方法給了我這個例外:

AnnotationException: referencedColumnNames(f1, f2) of entity.BPK.bpk.a 
referencing com.example.entity.A not mapped to a single property 

能否請你幫忙嗎?

+0

JPA不允許部分主鍵。 B需要A的每個主鍵字段的外鍵來唯一標識A.如果只有f1和f2唯一標識一個A,那麼它們應該是它的主鍵(而不是f2和f3)。 – Chris

+0

非常感謝克里斯。這清除了我的問題!在這種情況下,我必須在APK中將f3和f4註釋爲@Basic,而不是id或embeddedId。我只使用此服務來選擇,所以我想它沒關係? – Mjasmin

+0

f3和f4不應該在APK中,只是以A爲基礎。 – Chris

回答

0

假設f1和F2唯一標識A並存在於APK中,您可以通過幾種方式使用JPA 2.0的派生ID。最簡單的顯示是:

這裏
@Entity 
@IdClass(BPK.class) 
public class B { 
    @ID 
    String f5; 
    @ID 
    String f6; 
    @ID 
    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumns({ 
    @JoinColumn(name="f1", referencedColumnName="f1", nullable=false), 
    @JoinColumn(name="f2", referencedColumnName="f2", nullable=false) 
    }) 
    A a; 
} 

public class BPK { 
    String f5; 
    String f6; 
    APK a; 
} 

關鍵點是B必須一個是控制foriegn重點領域F1和F2的引用,A的主鍵使用B的主鍵內 - 具有相同的名稱爲關係。繪製它的另一種方法是使B的PK的embeddid ID,但嵌入的ID仍不能有引用映射,所以它可能看起來:

@Entity 
@IdClass(BPK.class) 
public class B { 
    @EmbeddedId 
    BPK pk; 
    @MapsId("apk") 
    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumns({ 
    @JoinColumn(name="f1", referencedColumnName="f1", nullable=false), 
    @JoinColumn(name="f2", referencedColumnName="f2", nullable=false) 
    }) 
    A a; 
} 

@Embeddable 
public class BPK { 
    String f5; 
    String f6; 
    APK apk; 
} 

通知的mapsId - 這告訴JPA在嵌入式中的列「 apk'引用使用從A引出的引用映射中的外鍵字段。JPA將從引用映射中爲您填充外鍵,這對於使用排序的情況很重要。