我正在设置一个基于 JPA 规范的存储库实现,该实现利用 jpa 规范(基于 RSQL 过滤器字符串构建)来过滤结果、定义结果排序并通过“不同”删除任何重复项,否则这些重复项将因连接表而返回。JPA 规范构建器方法连接多个表并设置“不同”标志:
final Join<Object, Object> rootJoinedTags = root.join("tags", JoinType.LEFT);
final Join<Object, Object> rootJoinedLocations = root.join("location", JoinType.LEFT);
...
query.distinct(true);
Run Code Online (Sandbox Code Playgroud)
为了允许按连接表列排序,我已将“HINT_PASS_DISTINCT_THROUGH”提示应用于相关存储库方法(否则,按连接表列排序会返回类似“排序列必须包含在 SELECT DISTINCT 查询中”的错误) 。
@QueryHints(value = {
@QueryHint(name = org.hibernate.jpa.QueryHints.HINT_PASS_DISTINCT_THROUGH, value = "false")
})
Page<SomeEntity> findAll(@Nullable Specification<SomeEntity> spec, Pageable pageable);
Run Code Online (Sandbox Code Playgroud)
所述存储库方法的参数构造如下:
final Sort sort = getSort(searchFilter);
final Specification spec = getSpecificationIfPresent(searchFilter);
final PageRequest pageRequest = PageRequest.of(searchFilter.getPageNumber(), searchFilter.getLimit(), sort);
return eventRepository.findAll(spec, pageRequest);
Run Code Online (Sandbox Code Playgroud)
经过这些更改后,过滤和排序似乎按预期工作。但是,该提示似乎会导致在构建结果页面后应用“不同”过滤,从而将页面中返回的实体数量从配置的“大小”PageRequest 参数减少到过滤重复项后留下的任何内容出去。例如,如果我们使用“page=0”和“pageSize=10”创建一个 PageRequest,那么生成的 Page 可能仅返回 5 个“SomeEntity”实例,尽管数据库包含更多条目(准确地说是 177 个实体)这个案例)。如果我删除提示,则返回的实体编号再次正确。
问题:有没有办法使相同的规范查询设置与正确大小的页面一起工作(可能会添加一些其他提示以在构造页面对象之前执行重复过滤)?如果没有,那么我是否可以使用另一种方法来实现所需的基于规范的过滤,以及与“不同”一样的连接列排序和重复删除?
PS:PostgreSQL 是相关应用程序背后的数据库