[英]Alternative to fetch join with “ON clause” in Hibernate
給定的是RDBMS中的以下域模型,它與Hibernate映射到Java對象中。
┌─────────┐ ┌─────────────┐
│ Project │ 1 0..n │ UserSetting │
├─────────┼------------┼─────────────┤
│ name │ │ username │
└─────────┘ │ favorite │
└─────────────┘
用戶可以將項目標記為收藏,這由關聯(可選) UserSetting
條目反映。 如果用戶沒有標記項目,則數據庫中沒有UserSetting
條目 ,這意味着項目不是最喜歡的。 認為UserSetting
是“稀疏的”。
另外給出:實體應該通過JPA以Hibernate作為提供者獲取。
假設Project
和UserSetting
表可能非常大。 優化數據庫架構不應受此問題的影響。 假設存在有效的索引。
對於給定的用戶,我希望有效地獲取所有項目,包括該特定用戶的最愛狀態。 注意排序標准!
我最初的方法是制定以下JPQL查詢:
SELECT p, us FROM Project p
LEFT JOIN FETCH UserSetting us
WHERE us.username IS NULL OR us.username = :currentUser
ORDER BY COALESCE(us.favorite, false) DESC, p.name ASC
如果這不起作用currentUser
沒有 UserSetting
但userB
了。 該UserSetting
的userB
將被加入,但該項目將不會列出由於WHERE
子句。
幸運的是, JPA 2.1引入了JOINS和ON子句 ( Javadoc ),可用於將查詢重新表述為:
SELECT p, us FROM Project p
LEFT JOIN FETCH UserSetting us
ON us.username IS NULL OR us.username = :currentUser
ORDER BY COALESCE(us.favorite, false) DESC, p.name ASC
不幸的是,Hibernate(4.3.6)不支持使用“ ON子句 ”(Hibernate的語言中的“ WITH子句 ”)進行提取連接,並退出時出現以下異常:
org.hibernate.hql.internal.ast.QuerySyntaxException: with-clause not allowed on fetched associations; use filters
如何重新構造查詢以實現功能並滿足我的約束:
您可以使用以下命令檢索沒有UserSettings的Project:
SELECT p, us FROM Project p
LEFT JOIN FETCH UserSetting us
WHERE us is null OR us.username IS NULL OR us.username = :currentUser
ORDER BY COALESCE(us.favorite, false) DESC, p.name ASC
該
us is null
在查詢的WHERE子句中的部分功能。
最近的發現是JPA 2.1(JSR 338)規范定義了語法而沒有允許用於獲取連接的“ON子句”。
我的解決方法是省略Hibernate的對象映射功能,並明確選擇Project
和UserSetting
所需的字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.