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 Parents:
@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
Catand only be able to putKittenoffsprings into its set. Or an object ofPuppyand only be able to setDogas its parent. - To be able to query for all
Parents and for it to keep its typing so that onlyOffspringcan 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.