一对多关联 - 在JPA中使用非主键列连接表

12

我正在处理一个遗留系统,需要从数据库中读取一些信息。以下是表之间的关系:

供应商(vendorId - pk,vendorEid,名称)
供应商联系人桥接表(bridgeId -pk,vendorEid,contactEid)
联系人(contactId -pk,contactEid,电话)

vendorEid和contactEid不是表的主键,但在连接表VendorContactBridge中用作连接列。

供应商实体 -

@Entity
@Table(name="Vendor")
public class Vendor implements Serializable{

@Id
@Column(name="VENDORID")
private BigDecimal vendorId;

@Column(name="VENDOREID")
private BigDecimal vendorEid;

@OneToMany(fetch = FetchType.EAGER)
@JoinTable(name="VENDORCONTACTBRIDGE", 
joinColumns={@JoinColumn(name="VENDOREID", referencedColumnName="VENDOREID")},
inverseJoinColumns={@JoinColumn(name="CONTACTEID", referencedColumnName="CONTACTEID")})
private Set<Contact> vendorContact;
}

联系实体 -

@Entity
@Table(name="CONTACT")
public class Contact implements Serializable{

@Id
@Column(name="CONTACTID")
private BigDecimal contactId;

@Column(name="CONTATEID")
private BigDecimal contactEId;

@ManyToOne
@JoinTable(name="VENDORCONTACTBRIDGE", 
joinColumns={@JoinColumn(name="CONTACTEID", referencedColumnName="CONTATEID")},
inverseJoinColumns={@JoinColumn(name="VENDOREID", referencedColumnName="VENDOREID")})
private Vendor vendor;
 }

在运行查询时,出现以下异常:

SecondaryTable JoinColumn 不能引用非主键。

我移除了 Vendor 实体中的 Eager fetch,虽然没有异常但是它没有加载集合。这个关联有什么问题吗?

2个回答

11
根据第 JPA 2.0规范 第11.1.21段在第379页的JoinColumn注释,对于被引用表中不是主键列的引用列的支持是可选的。使用这种映射的应用程序将不具有可移植性。似乎Hibernate选择不实现这个可选部分。其他实现可能会。我在EclipseLink上尝试了它,但它也不能工作(验证失败)。我看到两个解决方法。一个是调整你的模式,使用主键,从数据库设计理论的角度来看这是正确的事情。然而,由于其他软件依赖于这个模式,这可能不是一个选项,因此只能采用第二个选项,在JPA中不对关系进行建模,只使用eid并自己检索相关对象。

选项2:你的意思是,我应该进行两个数据库调用,一个是基于VendorEid从VendorContactBridge获取ContactEid,然后再基于ContactEid获取Contact?我的理解正确吗? - Pankaj
这是基本原则。但最好使用本地查询,因为您可以执行联接操作,从而使用单个SQL查询检索对象。 - Eelke

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接