Java Hibernate:为两个不同的类映射同一列

Java Hibernate:为两个不同的类映射同一列,java,hibernate,jpa,hibernate-mapping,Java,Hibernate,Jpa,Hibernate Mapping,我在一个遗留系统上工作,它没有一个合适的单元测试,也没有任何测试,所以我需要非常小心我在系统中所做的任何更改 我的基本情况是: 我有一个人和地址有很多关系,我不能改变这种关系。但是要知道地址有几种类型,例如:帐单地址和邮寄地址 public class Person { @Id @Column(name = "PERSON_ID") @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(name

我在一个遗留系统上工作,它没有一个合适的单元测试,也没有任何测试,所以我需要非常小心我在系统中所做的任何更改

我的基本情况是: 我有一个人和地址有很多关系,我不能改变这种关系。但是要知道地址有几种类型,例如:帐单地址和邮寄地址

public class Person {

@Id
@Column(name = "PERSON_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

@Column(name = "PERSON_NAME")
private String personName;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ADDRESS_ID")
private Address address;

getters and setters
地址类

public class Address {

private static final long serialVersionUID = 1L;

@Id
@Column(name = "ADDRESS_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Column(name = "STREET_1_NAME")
private String street1Name;

@Column(name = "STREET_2_NAME")
private String street2Name;

getters and setters
我正在考虑将列ADDRESS_类型添加到ADDRESS表中,但我正在努力实现它。我只想拥有一个类型为Address的新属性postalAddress,并像获取postalAddress一样轻松地获取postalAddress。

hust添加:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "POSTAL_ADDRESS_ID")
private Address postalAddress;
这将向管理关系的
Person
表中添加一个新列。
无需将
地址\u TYPE
添加到
地址
表中,因为它将是多余的。

我之前的评论听起来像是您希望使用地图从一个人到多个地址

按照建议添加地址类型列,并创建枚举地址类型(邮政、账单):

本人:

//there are various MapKey annotations however, without testing I think these are what you need
@OneToMany
@MapKeyEnumerated(EnumType.String) //tells Hibernate we want the type to contain BILLING/POSTAL etc rather than the ENUM ordinals (0,1 etc)
@MapKeyColumn(name ="address_type")
private Map<AddressType, Address) addresses;

public Address getPostalAddress(){
return addresses.get(AddressType.POSTAL);
}

public Address getBillingAddress(){
return addresses.get(AddressType.Billing);
}

//or even
public Address getAddress(AddressType type){
return addresses.get(type);
}
//但是有各种MapKey注释,如果不进行测试,我认为这些就是您需要的
@独身癖
@MapKeyEnumerated(EnumType.String)//告诉Hibernate我们希望该类型包含账单/邮政等,而不是枚举序号(0,1等)
@MapKeyColumn(name=“地址\类型”)

private Map谢谢Alan,你的建议很有帮助,但我最终使用了InheritanceType,因为它与遗留代码兼容

我的Address类现在看起来像:

@Entity
@Table(name = "ADDRESS")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="ADDRESS_TYPE",
    discriminatorType=DiscriminatorType.INTEGER
)
@DiscriminatorValue("null")

public class Address  {
@Entity
@Table(name = "ADDRESS")
@DiscriminatorValue(value="2")
public class PostalAddress extends Address {

    private static final long serialVersionUID = 1L;

    @ManyToOne
    @JoinColumn(name = "INSURED_ID")
    private Insured insured;

    public void setInsured(Insured insured) {
        this.insured = insured;
    }

    public Insured getInsured() {
        return insured;
    }

}
我的邮服看起来像:

@Entity
@Table(name = "ADDRESS")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="ADDRESS_TYPE",
    discriminatorType=DiscriminatorType.INTEGER
)
@DiscriminatorValue("null")

public class Address  {
@Entity
@Table(name = "ADDRESS")
@DiscriminatorValue(value="2")
public class PostalAddress extends Address {

    private static final long serialVersionUID = 1L;

    @ManyToOne
    @JoinColumn(name = "INSURED_ID")
    private Insured insured;

    public void setInsured(Insured insured) {
        this.insured = insured;
    }

    public Insured getInsured() {
        return insured;
    }

}
因此,对于过去插入的没有类型的地址,我假设
null
,并且为了兼容性,新的地址也将是“null”,只是PostalAddress将是“2”

我的个人课看起来像

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ADDRESS_ID")
private Address address;

@Transient
private PostalAddress postalAddress;

我知道这听起来很奇怪,但有人要求我和一个1-N邮递员建立关系。

只是想澄清一下:从一个人到一个地址的关系是多对一的?每个人都有一个地址,每个地址可以属于许多人。这是正确的吗?从你的问题来看,听起来你想反过来。每个人都有多个地址:账单、邮政等。是的,你说得对,这就是我拥有的和我想要的。