简体   繁体   中英

Inefficient JPA query using compound Where clause

I have a tables with One-Many Relationships as follows

City->School->Teacher->Children

and my JPQL for retrieving children from a city is as below

@Query("Select c  from Children c where c.teacher.school.city=:city")
Set<Children> findChildrenFromCity(@Param("city") City city);

This reference here about Where clause says that

"Compound path expressions make the where clause extremely powerful."

However, upon observing the logs I realise that the above query is doing strange things like

  1. Generate multiple Selects instead of one Select

  2. Some cross joins can be seen in the logs

I am trying to understand if I am defining my query correctly and if the compound Where is indeed so powerful, why is my query so inefficient.

You can use the following method:

Set<Children> findAllByTeacherSchoolCity(String city);

assuming, that your class Children has field Teacher teacher , Teacher has School school and School has String city .

In case there are differences, please ask in comments for clarification.

Try this

@Query("Select c from City city join city.schools s join s.teachers t join t.childrens c where city = :city")
Set<Children> findChildrenFromCity(@Param("city") City city);

This query is running exactly one Select query to fetch the Children entities. Check the below mentioned logs.

HIBERNATE: SELECT childrens3_.id AS id1_0_, childrens3_.date_created AS date_cre2_0_, childrens3_.date_updated AS date_upd3_0_, childrens3_.NAME AS name4_0_, childrens3_.teacher_id AS teacher_5_0_ FROM city city0_ INNER JOIN school schools1_ ON city0_.id = schools1_.city_id INNER JOIN teacher teachers2_ ON schools1_.id = teachers2_.school_id INNER JOIN children childrens3_ ON teachers2_.id = childrens3_.teacher_id WHERE city0_.id = ?

Now what you have is an n+1 issue. To fix such issue you can use join fetch instead of simple joins.

如果你想使用查询注释试试这个方法

@Query("Select c  from Children c join fetch c.teacher t join fetch t.school s join fetch s.city ct where ct.id = :id")

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