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 规范的信息,这就是我的发现:
The join condition used for a join comes from the mapping's join
columns. This means that the JPQL user is normally free from having to
know how every relationship is joined. In some cases it is desirable
to append additional conditions to the join condition, normally in the
case of outer joins. This can be done through the ON clause. The ON
clause is defined in the JPA 2.1 specifiation, and may be supported by
some JPA providers.
EclipseLink : Hibernate : TopLink - support the ON clause.
应该注意的是,这种类型的查询对我一点帮助都没有,因为在这个查询中有时我会得到空值,在连接表之后使用 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
你是对的,当你添加 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。
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")
没有替代解决方案,因为当您有这样的谓词时:
and (p is NULL OR p.status = :postStatus)
然后出现3个案例:
- getPostsList() returns 空列表
- getPostsList() returns 列出至少一个具有查询状态的元素
- getPostsList() returns 没有元素具有查询状态的列表
在第 3 种情况下的状态下,您将完全失去 Campaign 的所有行。但是获取具有 1 个状态的
因为当postList的列表不为空时left join不会join nulls.
我有这样的 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 规范的信息,这就是我的发现:
The join condition used for a join comes from the mapping's join columns. This means that the JPQL user is normally free from having to know how every relationship is joined. In some cases it is desirable to append additional conditions to the join condition, normally in the case of outer joins. This can be done through the ON clause. The ON clause is defined in the JPA 2.1 specifiation, and may be supported by some JPA providers. EclipseLink : Hibernate : TopLink - support the ON clause.
应该注意的是,这种类型的查询对我一点帮助都没有,因为在这个查询中有时我会得到空值,在连接表之后使用 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
你是对的,当你添加 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。
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")
没有替代解决方案,因为当您有这样的谓词时:
and (p is NULL OR p.status = :postStatus)
然后出现3个案例:
- getPostsList() returns 空列表
- getPostsList() returns 列出至少一个具有查询状态的元素
- getPostsList() returns 没有元素具有查询状态的列表
在第 3 种情况下的状态下,您将完全失去 Campaign 的所有行。但是获取具有 1 个状态的
因为当postList的列表不为空时left join不会join nulls.