Вы можете использовать @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
class.
@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
, чтобы сопоставить внешние ключи со столбцами xId
и yId
вашей таблицы Person.Без этих аннотаций 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
}