Reputation: 4267
I have to make a particular query using Hibernate.
The following classes are just a simple example, to make easier for you to understand my scenario and my goal. I made up the example while writing this post, I hope I didn't make errors (anyway don't pay attention to the errors :D).
class Father{
int id;
@OneToMany(mappedBy = "father", fetch = FetchType.LAZY)
List<Son> sonList;
}
class Son{
@ManyToOne(targetEntity=Father.class)
@JoinColumn(referencedColumnName = "id", name = "father")
Father father;
@OneToMany(mappedBy = "son", fetch = FetchType.LAZY)
List<Toy> toyList;
}
class Toy{
@ManyToOne(targetEntity=Son.class)
@JoinColumn(referencedColumnName = "id", name = "son")
Son son;
@OneToMany(mappedBy = "Feature", fetch = FetchType.LAZY)
List<Feature> featureList;
}
class Feature{
@ManyToOne(targetEntity=Toy.class)
@JoinColumn(referencedColumnName = "id", name = "toy")
Toy toy;
boolean unisex;
}
I have to select from the database a Father
with id = 1
, with his relative Son
, but only the sons that has a Toy
with Feature.unisex = true
.
I dunno how to reach the field Feature.unisex
of class Toy
.
With createAlias()
I can do:
Criteria criteria = session.createCriteria(Father.class);
criteria.createAlias("sonList", "sonListAlias");
criteria.add(Restrictions.idEq(1));
criteria.add(Restrictions.in("sonListAlias.toyList", toyList));
but I can't go further. I should need something like:
Criteria criteria = session.createCriteria(Father.class);
criteria.createAlias("sonList", "sonListAlias");
criteria.add(Restrictions.in("sonListAlias.toyList.featureList.unisex", unisex));
but, of course, this is not the right way to do it.
Thank you in advance.
Upvotes: 1
Views: 1145
Reputation: 19956
Firstly, please don't use unnecessary mapping properties. I mean targetEntity=Father.class
, referencedColumnName = "id", name = "father"
. And don't use names like sonList
, just sons
.
Criteria criteria = session.createCriteria(Father.class);
criteria.createAlias("sonList", "son");
criteria.createAlias("son.toyList", "toy");
criteria.createAlias("toy.featureList", "feature");
criteria.add(Restrictions.idEq(1));
criteria.add(Restrictions.eq("feature.unisex", true));
If you need to eagerly fetch sonList
, you can try to use setFetchMode("sonList", FetchMode.JOIN)
.
If you need to
"always" get a father and get only his sons that have toys that have Feature.unisex = true
you can try to use @Filter
Hibernate @Filter and @FilterJoinTable Annotation Example
But I think It will be better, if you load sonList
in a separate request
Criteria criteria = session.createCriteria(Son.class);
criteria.createAlias("father", "father");
criteria.createAlias("toyList", "toy");
criteria.createAlias("toy.featureList", "feature");
criteria.add(Restrictions.eq("father.id", 1));
criteria.add(Restrictions.eq("feature.unisex", true));
Upvotes: 2