【问题标题】:How to write a Hibernate query using the WITH clause to customize the ON clause如何使用 WITH 子句编写 Hibernate 查询以自定义 ON 子句
【发布时间】:2022-02-24 01:06:44
【问题描述】:

我正在使用以下 HQL 查询:

feeds = (List<Album>) session.createQuery(
                    "select distinct album from Album as album "
                    + "left join album.postImageses as pi with pi.isAlbumCover=:isCover "
                    + "where album.atom.id=:aid ")
                    .setParameter("isCover", "Yes")
                    .setParameter("aid", id)
                    .list();

此查询工作正常。 但问题是我只想从postImageses 获取 isAlbumCover 值为“是”的图像 但上面的查询正在获取所有图片(图片是否为专辑封面)。

那么我怎样才能使用isAlbumCover='Yes' 只获取图像(而不是其他)。 如何解决这个问题。

【问题讨论】:

  • 为什么要使用左连接?
  • 对于专辑图片可能有或没有所以我认为左加入好?您认为我应该使用哪个。

标签: sql hibernate join orm hql


【解决方案1】:

Hibernate 不能为您提供部分的一对多结果。你总是让所有孩子确保一致性。

您需要将查询颠倒过来:

select ps
from PostImage ps
inner join fetch ps.album albm
inner join fetch albm.atom atm
where ps.isAlbumCover = :isCover and atm.id = :aid

此查询假定您在专辑和 PostImage 之间具有双向关联,因此 PostImage 也具有 @ManyToOne 专辑引用。

为了证明这是不可能的,Hibernate documentation 是这么说的:

提取连接通常不需要分配别名,因为 关联对象不应在 where 子句(或任何 其他子句)。

所以 fetch 不受 where 子句的影响。在您的情况下,with 子句最多可以过滤根实体(专辑),但所有关联的集合(postImageses)都将受制于fetching policy

因为您没有明确使用 fetch 指令,这意味着查询将使用映射提取策略。如果一对多关联是 LAZY,则不会在此查询中初始化。一旦你访问它,Hibernate 将发出一个新的查询来初始化它,这就是 with 子句不过滤子集合的原因。

【讨论】:

  • PostImage 使用了错误的属性,所以我将其更改为:isAlbumCover。尝试使用左连接。也许您没有 Atoms for Albums。
  • 但是没有isAlbumCover的时候。那么它不会获取专辑名称。例如,我有 3 张专辑 a1 a2 a3,只有 a1 有封面图片,然后它不会同时提供 2 张专辑名称。
  • 应该有任何方法从连接中的集合中获取少量或指定的数据
  • Hibernate 只能加载完整集合,不能加载部分集合。因此,您要么加载所有图像并在之后过滤结果,要么选择图像,但您将不会拥有没有图像的相册。
  • 那么需要with子句
猜你喜欢
  • 2014-09-28
  • 1970-01-01
  • 2017-11-12
  • 2021-02-21
  • 2020-06-05
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多