Spring Data JPA 规范 - 连接中的不同+按列排序

Posted

技术标签:

【中文标题】Spring Data JPA 规范 - 连接中的不同+按列排序【英文标题】:Spring Data JPA Specifications - Distinct + order by column in join 【发布时间】:2020-10-10 19:43:01 【问题描述】:

我有一些规范要与“and”结合:

Specification.where(predicate1).and(predicate2).and(predicate3);

其中一个有不同的集合:

query.distinct(true);

另一个人对连接中的列进行排序。

query.orderBy(builder.desc(bJoin.get("orderbyColumn")));

这会失败,并出现 SQLGrammarException 说明按列的顺序应该是不同的。

所以基本上我们有实体 A、主实体和一些嵌套实体 B,我们从 A 中选择但想按 B 排序,并且在生成的 sql 中它只从 A 中选择列。我找到的唯一方法工作(= 也使它从 B 中选择)是用 fetch 替换连接:

Fetch < A, B > bFetch = root.fetch("joinCol", JoinType.INNER);
Join < A, B > bJoin = (Join < A, B > ) bFetch;

工作了一段时间,在 H2 本地测试,但过了一段时间又开始出现另一个错误:

org.hibernate.QueryException: 查询指定连接提取,但是 选择列表中不存在获取的关联的所有者

我在本地指向 H2 时以某种方式解决了它,方法是要求某些列不为空,但在使用 PostgreSQL 的真实服务器中,它根本不起作用,在存在提取的所有情况下都会出现该错误。

我的问题是:在未获取的嵌套实体上使用 distinctorderby 的正确方法是什么?我的 fetch 解决方案是否正常,只需要修复(如果是的话如何修复?)还是我应该完全选择另一个选项?

对于实际查询,我使用的是这种方法:

findAll(Specification<>, Pageable)

有没有办法让 distinct 用 order by (某种子查询?)包装整个查询并绕过所有这些噩梦?让它生成这样的查询:

select distinct colA1, colA2, coAl3 from (select colA1, colA2, coAl3 

from A inner join B b on ........ order by b.colB1)

我是否需要手动将我的规范转换为谓词并用它做其他事情来尝试解决我的问题(某种混合方法)?

任何建议都将不胜感激。

【问题讨论】:

嗨,它对我帮助很大。有什么想法如何以某种深入的方式处理它?多次获取导致多包异常。 【参考方案1】:

我遇到了同样的错误,但实际上不是错误:)

findAll(Specification, Pageable) 这个方法会抛出 2 个不同的查询。

第一个是计数查询,您必须小心。 其次是您实际执行的行查询。

您可以使用下面的代码检查查询类型

if (query.getResultType() != Long.class && query.getResultType() != long.class)
   root.fetch("entity1");
 

【讨论】:

您好,马上试试,谢谢。可以肯定的是,当您说相同的错误时,您是指与 fetch 相关的错误吗? (我列出了关于 fetch 和 distinct 的错误)所以你把它放在使用 fetch 的代码或你的所有规范中? 第一个查询是计数查询,这就是您收到错误的原因。 你可以在 if 子句中使用 fetch 谢谢,现在就试试,可能需要稍微玩一下我的代码,因为正如你在上面看到的,我正在转换为 fetch 加入,但我会基于这个常规加入或根据您提供的条件获取加入,将迅速报告,再次感谢。 最后一个问题,记录在哪里?我的意思是对于一个真正想要完成这项工作的人来说,这是否真的记录在某个地方?还是人们调试该问题的反复试验?

以上是关于Spring Data JPA 规范 - 连接中的不同+按列排序的主要内容,如果未能解决你的问题,请参考以下文章

使用连接的 Spring Data JPA 规范的不同结果

Spring Data JPA方法定义规范

使用连接表存储库的@manytomany 中的 Spring 数据 jpa 规范和可分页

Spring Data JPA:使用连接表进行排序和分页

处理 JPA 规范和 spring-data-jpa 时如何使用声明 Stream 作为返回类型

Spring Data JPA 的作用.