簡體   English   中英

JPQL 查詢 - 休眠:提取的關聯不允許帶子句

[英]JPQL query - hibernate: with-clause not allowed on fetched associations

我有這樣的 JPA 存儲庫和 JPQL 查詢:

@Query("SELECT c from Campaign c" +
        " left join fetch c.postsList p on p.status = :postStatus" +
        " left join fetch p.platform" +
        " left join fetch c.campaignStatistics stat on stat.updateDate = :updateDate" +
        " where c.id =:id")
Campaign findCampaignWithPosts(
        @Param("id") Long id,
        @Param("postStatus") PostStatus postStatus,
        @Param("updateDate") LocalDate updateDate);

但它不起作用。 我得到:

org.hibernate.hql.internal.ast.QuerySyntaxException: with-clause not allowed on fetched associations; use filters

我去研究了有關 JPA 2.1 規范的信息,這就是我發現的:

用於連接的連接條件來自映射的連接列。 這意味着 JPQL 用戶通常不必知道每個關系是如何連接的。 在某些情況下,需要向連接條件附加附加條件,通常是在外部連接的情況下。 這可以通過 ON 子句來完成。 ON 子句在 JPA 2.1 規范中定義,並且某些 JPA 提供程序可能支持。 EclipseLink : Hibernate : TopLink - 支持 ON 子句。

應該注意的是,這種類型的查詢根本沒有幫助我,因為在這個查詢中有時我會得到空值,在連接表之后使用 where 子句。

   @Query("SELECT c from Campaign c" +
            " left join fetch c.postsList p" +
            " left join fetch p.platform" +
            " left join fetch c.campaignStatistics stat" +
            " where c.id =:id" +
            " and p.status = :postStatus" +
            " and stat.updateDate = :updateDate")

在這種情況下該怎么辦? 除了如何使用本機查詢之外,沒有其他解決方案嗎? 但是幾乎所有 JPQL 查詢的含義都丟失了。 我使用休眠版本 5.2.12

您是對的,當您添加 p.status = :postStatus 時,它會過濾掉聯接右側不存在的結果(即,當 Campaign 沒有帖子時)。

對我有用的是添加一個 OR 子句來接受連接右側為 NULL 的情況。

所以,你應該用and (p IS NULL OR p.status = :postStatus)替換and p.status = :postStatus

所以這個請求應該有效:

@Query("SELECT c from Campaign c" +
            " left join fetch c.postsList p" +
            " left join fetch p.platform" +
            " left join fetch c.campaignStatistics stat" +
            " where c.id =:id" +
            " and (p is NULL OR p.status = :postStatus)" +
            " and stat.updateDate = :updateDate")

至於您收到的錯誤消息,我認為您不應該添加ON子句,因為 JPA/Hibernate 已經處理了它。

我正在使用 Hibernate 5.0.12。

沒有替代解決方案,因為當您有這樣的謂詞時:

and (p is NULL OR p.status = :postStatus)

然后出現3種情況:

  1. getPostsList() 返回空列表
  2. getPostsList() 返回包含至少一個具有查詢狀態的元素的列表
  3. getPostsList() 返回沒有查詢狀態元素的列表

在 3 種情況下,您將完全丟失帶有 Campaign 的所有行。 但是獲取具有 1 個狀態的那些

因為左連接不會連接空值,當 postList 的列表不為空時

在獲取別名時使用 WHERE 條件不是一個好主意

嘗試這個

@Query("SELECT c from Campaign c" +
        " left join c.postsList p" +
        " left join fetch c.postsList " +
        " left join fetch p.platform " +
        " left join c.campaignStatistics stat" +
        " left join fetch c.campaignStatistics " +
        " where c.id =:id" +
        " and (p is NULL OR p.status = :postStatus)" +
        " and stat.updateDate = :updateDate")

暫無
暫無

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

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