答案 0 :(得分:2)
您可以使用@Embeddable
映射两个实体的组合主键,并在@MapsId
实体的地址属性上使用User
注释以共享主键。
但是在向您展示映射之前,请注意User
是大多数数据库中的保留字。我建议您为实体选择其他名称。在我的示例中,我将其更改为Person
。
让我们从映射主键的@Embeddable
开始。我将类命名为AddressKey
。这是一个简单的Java类,实现了Serializable
接口,并具有属性xId
和yId
。您还需要实现equals
和hashCode
方法。
@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
实体的主键。
您还需要用2个address
注释来注释@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
}