在我的項目上,我使用Groovy和Spring Data JPA的Specification
來構建Hibernate查詢。使用JPA標準,我如何獲取未加入實體的連接實體的子實體?
我不能提供我的實際查詢,但爲了說明我的問題讓我們說我有建築實體,每個建築物都有樓層,每個樓層都有房間和Windows。
我試圖模仿行爲是這樣的原生SQL查詢:
SELECT b.*, r.*
FROM building b
INNER JOIN floor f ON b.id = f.building_id
INNER JOIN window w ON f.id = w.floor_id
LEFT OUTER JOIN room r ON f.id = r.floor_id
WHERE w.id = 1;
我有類似以下規範:
public class MySpec implements Specification<Building> {
@Override
public Predicate toPredicate(final Root<Building> root, final CriteriaQuery<?> query, final CriteriaBuilder cb) {
final Join floorsJoin = root.join("floors");
final Join windowsJoin = floorsJoin.join("windows");
//I'd like to remove this line
final Fetch floorsFetch = root.fetch("floors"); // <---
floorsFetch.fetch("rooms", JoinType.LEFT);
cb.equal(windowsJoin.get("id"), 1L);
}
}
標註出來的線是我的問題。如果我離開它,生成的查詢看起來是這樣的:
SELECT b.*, f2.*, r.*
FROM building b
INNER JOIN floor f ON b.id = f.building_id
INNER JOIN window w ON f.id = w.floor_id
INNER JOIN floor f2 ON b.id = f2.building_id
LEFT OUTER JOIN room r ON f2.id = r.floor_id
WHERE w.id = 1;
(注意的floor
重複INNER JOIN
和不必要的f2.*
數據)
如果我刪除它,並使用floorsJoin
,而不是獲取客房,我得到以下休眠錯誤:
org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list
的不需要的f2.*
數據將是美好的,除了我不能與T代替上面floorsJoin
他floorsFetch
,因爲我需要加入windows
表(不提取windows
)和Fetch
類沒有.join
方法。
我很難搞清楚如何完成我所需要的工作,同時仍然生成單個查詢;當然,我一定會錯過簡單的東西。
任何想法或建議,你可以提供將不勝感激。
非常感謝, B.J.