首页 > 解决方案 > 具有复合主键的一对一双向映射

问题描述

有人可以帮助我使用 Hibernate/JPA 的复合主键为以下关系进行双向一对一 JPA 映射吗? 在此处输入图像描述

标签: hibernatejpamappingone-to-onecomposite-primary-key

解决方案


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

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

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

@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 表的xIdyId列。如果没有这些注释,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
}

推荐阅读