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

时间:2019-01-25 13:36:06

标签: hibernate jpa mapping one-to-one composite-primary-key

有人可以帮我通过使用Hibernate / JPA的复合主键为以下关系进行双向一对一的JPA映射吗? enter image description here

1 个答案:

答案 0 :(得分:2)

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

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

让我们从映射主键的@Embeddable开始。我将类命名为AddressKey。这是一个简单的Java类,实现了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类的主键。

@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表的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
}
相关问题