我有这样的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
答案 0 :(得分:3)
你是对的,当你添加和p.status =:postStatus时,它会过滤掉连接右侧不存在的结果(即当广告系列没有帖子时)。
对我有用的是添加一个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。
答案 1 :(得分:1)
没有替代解决方案,因为当您有这样的谓词时:
and (p is NULL OR p.status = :postStatus)
然后出现3个案例:
在 3 种情况下,您将完全丢失带有 Campaign 的所有行。但是获取 1 个状态的
因为left join不会加入null,当postList的list不为空时。
答案 2 :(得分: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")