簡體   English   中英

替代在Hibernate中使用“ON子句”獲取連接

[英]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作為提供者獲取。

假設ProjectUserSetting表可能非常大。 優化數據庫架構不應受此問題的影響。 假設存在有效的索引。

對於給定的用戶,我希望有效地獲取所有項目,包括該特定用戶的最愛狀態。 注意排序標准!

我最初的方法是制定以下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 沒有 UserSettinguserB了。 UserSettinguserB將被加入,但該項目將不會列出由於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

如何重新構造查詢以實現功能並滿足我的約束:

  • 固定域模型
  • 有效擴展的高效查詢
  • JPA + Hibernate
  • 應避免使用Hibernate特定功能

您可以使用以下命令檢索沒有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的對象映射功能,並明確選擇ProjectUserSetting所需的字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM