JPQL查询 - hibernate:在获取的关联上不允许使用with子句

问题描述 投票:3回答:2

我有这样的JPA Repository和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子句。

应该注意的是,这种类型的查询对我没有任何帮助,因为在这个查询中,有时我得到null,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查询的含义都丢失了。我使用的是hibernate 5.2.12版

java hibernate jpa join jpql
2个回答
3
投票

你是对的,当你添加和p.status =:postStatus时,它会筛选出连接右侧不存在的结果(即当Campaign没有帖子时)。

对我有用的是添加一个OR子句来接受连接右侧为NULL的情况。

所以,你应该用and p.status = :postStatus替换and (p IS NULL OR 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。


0
投票

这是not a good idea在获取别名时使用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")
© www.soinside.com 2019 - 2024. All rights reserved.