Hello,
I have the following scenario, where I’d like more than one objects to have a “has a” relationship to the same type of object.
For instance… A person can have addresses as follows:
@Entity
@Table(name = “PERSON”)
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "PERSON_ID", unique = true, nullable = false)
private Integer personId;
@OneToMany
@JoinTable(joinColumns = @JoinColumn(name = "ADDRESS_ID"), inverseJoinColumns = @JoinColumn(name = "PERSON_ID"))
private Collection<Address> addresses = null;
// Getters and Setters ommitted for brevity
}
@Entity
@Table(name = “ADDRESS”)
public class Address {
@ManyToOne
@JoinColumn(name = "PERSON_ID")
private Person person;
// Getters and Setters ommitted for brevity
}
But now if I want to introduce a new class, that has no relationship to the Person class, but also has addresses… for instance:
@Entity
@Table(name = “BUILDING”)
public class Building {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "BUILDING_ID", unique = true, nullable = false)
private Integer buildingId;
@OneToMany
@JoinTable(joinColumns = @JoinColumn(name = "ADDRESS_ID"), inverseJoinColumns = @JoinColumn(name = "BUILDING_ID"))
private Collection<Address> addresses = null;
// Getters and Setters ommitted for brevity
}
Then I will also need to add an additional Fk in my addresses class:
@Entity
@Table(name = “ADDRESS”)
public class Address {
@ManyToOne
@JoinColumn(name = "PERSON_ID")
private Person person;
@ManyToOne
@JoinColumn(name = "BUILDING_ID")
private Building building;
// Getters and Setters ommitted for brevity
}
This works, however it’s inconvenient and it seems like an inneficient design pattern, to have a different foriegn key column for each object that stores addresses. In the application that I’m working on, Addresses are associated to many different objects that don’t have any relationship to eachother, so this would result in quite a few fk columns.
I’ve been researching and considering solving this problem one of two ways, but I’m not sure if either are the correct way to go.
One thought:
Create a super class
@Entity
@Table(name = “PERSISTENT_OBJECT”)
public class PersistentObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "PERSISTENT_OBJECT_ID", unique = true, nullable = false)
private Integer persistentObjectId;
}
The idea would be that each object would extend the persistent object class as follows:
@Entity
@Table(name = “PERSON”)
public class Person extends PersistentObject {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "PERSON_ID", unique = true, nullable = false)
private Integer personId;
@OneToMany
@JoinTable(joinColumns = @JoinColumn(name = "ADDRESS_ID"), inverseJoinColumns = @JoinColumn(name = "PERSON_ID"))
private Collection<Address> addresses = null;
// Getters and Setters ommitted for brevity
}
@Entity
@Table(name = “ADDRESS”)
public class Address extends PersistentObject {
@ManyToOne
@JoinColumn(name = "PERSON_ID")
private Person person;
@ManyToOne
@JoinColumn(name = "BUILDING_ID")
private Building building;
// Getters and Setters ommitted for brevity
}
and now when joining, I would want to have a generic column called “FORIEGN_KEY” and a “PERSISTENT_OBJECT_ID” such that each class that stores adresses joins to the address table using a composite key, which is the PERSISTENT_OBJECT_ID and the primary key of the actual object that the adress belongs to.
Option two, would be place a UUID column in the address
@Entity
public class Address {
@Id
@GeneratedValue(generator = “UUID”)
@GenericGenerator(
name = “UUID”,
strategy = “org.hibernate.id.UUIDGenerator”,
)
@Column(name = “id”, updatable = false, nullable = false)
private UUID id;
}
And then join to each of the classes that store adresses using that UUID, such that the UUID column is agnostic about which class is storing the address.
Any insight into whether or not either of these strategies will solve this problem, and if one is preferable would be greatly appreciated.
Thanks!!!