具有复合主键的一对一双向映射

One-to-One bi-directional mapping with composite primary key

有人可以帮我使用 Hibernate/JPA 使用复合主键为以下关系执行双向一对一 JPA 映射吗?

您可以使用 @Embeddable 映射两个实体的复合主键,并在 User 实体的地址属性上使用 @MapsId 注释来共享主键。

但在我向您展示映射之前,请注意 User 是大多数数据库中的保留字。我建议您为该实体选择一个不同的名称。在我的示例中,我将其更改为 Person.

让我们从映射主键的 @Embeddable 开始。我将 class 命名为 AddressKey。它是一个简单的 Java class,实现了 Serializable 接口并具有属性 xIdyId。您还需要实施 equalshashCode 方法。

@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 实体的主键。

您还需要使用 2 个 @JoinColumn 注释来注释 address 属性,以将外键映射到您的 Person xIdyId 列 table.如果没有这些注释,Hibernate 会将它们映射到列 address_xIdaddress_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
}