I have a parent class: Person
and two child classes: Hunter
and Policeman
. A Hunter
can have several Dog
, and a Policeman
can only have one Dog
. It's a unidirectional relationship, the Dog
entity only has an attribute breed
:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public class Person {
private String name;
and child classes:
@Entity
public class Hunter {
private String forest;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "hunter_id", referencedColumnName = "id")
private Set<Dog> dogs;
@Entity
public class Policeman {
private String city;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "dog_id")
private Dog dog;
It generates table structure like this:
person
id, name, forest, city, dog_id, person_type
dog:
id, breed, hunter_id
So essentially because the Policeman
only has one day, the dog's id FK is put in person
table. It would be null for rows that relate to a Hunter
.
And because a Hunter
has several dogs, the hunter's ID is put as a FK in the dog
table.
I picked this approach, because it provides compile-time checks - I can't possibly associate more than one dog with a Policeman
.
However, I've been wondering if it's a right approach and if it would have been better to just have person_id
FK in the dog
table and ensure that the Policeman
only has one dog in the service classes?
I picked this approach, because it provides compile-time checks - I can't possibly associate more than one dog with a Policeman.
That's true, but your approach allows the same dog to be associated with both a Policeman
and a Hunter
at the same time.
However, I've been wondering if it's a right approach and if it would have been better to just have
person_id
FK in thedog
table and ensure that thePoliceman
only has one dog in the service classes?
Yes, I would model the dog's associated person consistently with respect to the dog, regardless of the specific type of person. There are both practical and design reasons for this. For example, it prevents having one dog with two different people associated.
And if you wanted to do, you could still model Policeman
with a one-to-one relationship; it just needs to be owned by the Dog
side. That does leave room for inconsistency in the DB in the form of multiple dog records all associated with one policeman, but that's more or less a break-even: you're trading one means of inconsistency for another.