【发布时间】:2022-12-08 06:13:39
【问题描述】:
我正在尝试通过 JPA 选择一些计算数据。查询看起来像这样(示例非常简单):
@Query(value = """
SELECT
a.field1 as f1,
SUM(some clause using joined table) as f2,
SUM(some other clause using joined table) as f3
FROM EntityA a
LEFT JOIN EntityB b ON a.field1 = b.field1
WHERE a.field2 = :field2
""")
Page<ProjectionEntity> getSomeCalculatedData(String field2, Pageable pageable);
查询在没有 Pageable 参数的情况下运行良好。当我添加分页时,结果查询包含不存在的order by a.f2,因为EntityA不包含字段f2。
有没有办法以查询有效的方式构建实体结构和投影?
【问题讨论】:
-
首先,您应该对用于分页的结果进行排序。在反复执行查询时,数据库不保证结果的顺序相同,因此虽然页面大小符合预期,但您可能会看到其中一些结果出现相同的结果,或者根本看不到某些结果。我猜想,基于正在计算的 f2,Spring 的投影机制正在将它添加到您的查询中,这应该是一个错误。尝试添加您自己的订单,看看它是否停止。
-
Pageable 是分页和排序机制(正如您所写,当您对结果进行分页时,您必须对其进行排序以获得正确的结果)。问题是,从 Pageable 计算的订单字段被转换为问题中描述的实体字段。
-
似乎您已经知道并且正在将一些东西放入您的可分页对象中,让 spring 尝试将查询修改为“按 a.f2 排序”。 Spring 不是您标记问题的 JPA/Hibernate,它是 Spring(大概)错误地确定了可分页对象应该如何修改您的查询,而不仅仅是向它添加限制/偏移值,就像它对投影。您应该将其添加到您的问题中,我建议的一个潜在解决方法是向查询定义添加排序,而不是在使用计算字段时尝试通过可分页修改它。
标签: hibernate jpa pagination