2017-07-31 161 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将从引用映射中为您填充外键,这对于使用排序的情况很重要。