Reputation: 315
I'm working on a legacy system, that doesn't have a proper unit test, neither a any so I need to be very careful about any change that I do in the system.
The basic scenario that I have is: I got a Person that has a ManyToOne relationship with Address, I can't change this relationship. But know there are types of Address, for instance: billing address and post address.
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
address class
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
I'm thinking to add the column ADDRESS_TYPE to ADDRESS table, but I'm struggling on how to implement it. I just want to have a new attribute postalAddress of type Address and get the postalAddress as easy as just getPostalAddress.
Upvotes: 2
Views: 4598
Reputation: 315
Thanks Alan, your suggestion helped but I end up using InheritanceType because of compatibility with legacy code.
My Address class now looks like:
@Entity
@Table(name = "ADDRESS")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name="ADDRESS_TYPE",
discriminatorType=DiscriminatorType.INTEGER
)
@DiscriminatorValue("null")
public class Address {
My PostalAddress looks like:
@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;
}
}
So, for those addresses inserted in the past without a type I'm assuming null
and for compatibility the new ones will be 'null' as well, just the PostalAddress will be '2'.
And my Person class looks like
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ADDRESS_ID")
private Address address;
@Transient
private PostalAddress postalAddress;
I know it sounds odd, but I've been asked to have a relationship Person 1 - N PostalAddress.
Upvotes: 2
Reputation: 23246
Further to my previous comment sounds to me like you want a one-to-many from Person to Address using a Map.
Add the address_type column as you suggested and create an Enum AddressType (POSTAL, BILLING):
In Person:
//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);
}
Upvotes: 0
Reputation: 1785
hust add :
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "POSTAL_ADDRESS_ID")
private Address postalAddress;
this will add a new column to your Person
table managing the relation.
No need to add ADDRESS_TYPE
to ADDRESS
table since it will be redundant.
Upvotes: 0