简体   繁体   中英

Nested createAlias() in Hibernate

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.

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));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM