hibernate - 具有复合主键的一对一双向映射
解决方案
您可以使用 an@Embeddable
来映射两个实体的复合主键,并@MapsId
在您的实体的地址属性上使用注释User
来共享主键。
但在我向您展示映射之前,请注意这User
是大多数数据库中的保留字。我建议您为实体选择不同的名称。在我的示例中,我将其更改为Person
.
让我们从@Embeddable
映射主键的开始。我为班级命名AddressKey
。它是一个简单的 Java 类,它实现了Serializable
接口并具有属性xId
和yId
. 您还需要实现equals
andhashCode
方法。
@Embeddable
public class AddressKey implements Serializable {
private Long xId;
private Long yId;
public AddressKey() {}
public AddressKey(Long xId, Long yId) {
this.xId = xId;
this.yId = yId;
}
// omit getter and setter for readability
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((xId == null) ? 0 : xId.hashCode());
result = prime * result + ((yId == null) ? 0 : yId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AddressKey other = (AddressKey) obj;
if (xId == null) {
if (other.xId != null)
return false;
} else if (!xId.equals(other.xId))
return false;
if (yId == null) {
if (other.yId != null)
return false;
} else if (!yId.equals(other.yId))
return false;
return true;
}
}
如果使用 注释属性@EmbeddedId
,则可以使用AddressKey
可嵌入对象来映射类的主键Address
。
@Entity
public class Address {
@EmbeddedId
private AddressKey id;
private String city;
private String street;
private String country;
@OneToOne(mappedBy = "address")
private Person person;
// omit getter and setter methods
}
实体的映射Person
看起来很相似。除了主键映射之外,您还需要注释address
属性,该属性将关联映射到Person
实体,使用@MapsId
. 这告诉 Hibernate 它将使用关联Address
实体的主键作为实体的主键Person
。
您还需要address
使用 2 个注释对属性进行@JoinColumn
注释,以将外键映射到 Person 表的xId
和yId
列。如果没有这些注释,Hibernate 会将它们映射到列address_xId
和address_yId
.
@Entity
public class Person {
@EmbeddedId
private AddressKey id;
private String name;
private String society;
@OneToOne
@JoinColumn(name="xId", referencedColumnName="xId")
@JoinColumn(name="yId", referencedColumnName="yId")
@MapsId
private Address address;
// omit getter and setter methods for readability
}
推荐阅读
- javascript - 使用轮子事件更改类
- bash - 如何在循环中追加新行\ n
- javascript - 如何防止显示的实际文件路径检查网络终端
- python - 如何检查某些输入是否属于 sympy 函数?
- android - 如何同时从本地电话簿和谷歌联系人中获取所有联系人?
- android - ConstraintLayout that should support portrait and landscape modes -with a button to toggle full screen
- javascript - 如何在不模拟 ActivatedRouteSnapshot 的情况下测试角度防护/解析器
- go - 如何在 Github 上设置我的 Golang 项目版本
- python - 使用 GoogleNews-vectors-negative300.bin 构建字典返回 ValueError: could not convert string to float
- sql - 使用 JSON_MODIFY 更新 JSON