I have an inheritance issue where it is easier to explain the problem in code rather than text so given the following inheritance design for the Parent
s:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Parent<T extends Offspring> {
@OneToMany(mappedBy = "parent", targetEntity = Offspring.class)
private Set<T> offsprings;
// Getters/Setters relevant for all sub types
}
@Entity
public class Cat extends Parent<Kitten> {
}
@Entity
public class Dog extends Parent<Puppy> {
}
And the Offspring
:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Offspring<T extends Parent> {
@ManyToOne(targetEntity = Parent.class)
@JoinColumn(name = "parent_id", referencedColumnName = "id")
private T parent;
// Getters/Setters relevant for all sub types
}
@Entity
public class Kitten extends Offspring<Cat> {
}
@Entity
public class Puppy extends Offspring<Dog> {
}
Say I want to get a list of parents: List<Parent> parents = parentService.getAll();
The parent list, because it is now a raw type, has no understanding that the parents..get(0).getOffsprings()
should return a type Set<Offspring>
. It instead, because of the raw typing, thinks it returns Set
.
I might want to do this because a Person
might have a list of all their Parent
's like:
@Entity
public class Person {
@OneToMany(mappedBy = 'person')
private Set<Parent> parents;
}
And I might want to get all of the offspring of all the parents owned by the person: person.getParents().get(0).getOffsprings()
but this then returns a type Set
because it is a raw type.
Clearly I am going down the wrong route with this so:
The goals are:
- To be able to have an object of
Cat
and only be able to putKitten
offsprings into its set. Or an object ofPuppy
and only be able to setDog
as its parent. - To be able to query for all
Parent
s and for it to keep its typing so that onlyOffspring
can be put into the object.
I have gone through many different permutations of how this should be done. One option was for instance the Cat
object to hold its own container of Kitten
offspring:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Parent {
@OneToMany(mappedBy = "parent")
private Set<Offspring> offsprings;
}
@Entity
public class Cat extends Parent {
private Set<Cat> offsprings;
}
But this doesn't work because the Cat
class is unable to override the getter/setter for the parent class Parent
. As well as causing Hibernate issues because it now things that the database table Kitten
has a link to Cat
.
Disclaimer
I might be missing something obvious or going about this the whole wrong way so I am open to suggestions on the best way to handle this. Also my inheritance strategy might be causing the issues so all advice is welcome and I am happy to provide more if needed.