简体   繁体   English

Spring 数据 JPA 规格 - 不同 + 在连接中按列排序

[英]Spring Data JPA Specifications - Distinct + order by column in join

I have some specifications that I am combining with "and":我有一些与“and”结合的规范:

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

One of them has distinct set:其中一个有不同的集合:

query.distinct(true);

Another one makes an order by on a column that is in a join.另一个人对连接中的列进行排序。

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

This fails with a SQLGrammarException stating that order by column should be in distinct.这将失败,并出现SQLGrammarException ,说明按列的顺序应该是不同的。

So basically we have entity A, the main entity, and some nested entity B, we select from A but want to order by B, and in generated sql it only selects columns from A. The only way I found to make it work (= making it select from B as well) is to replace the join by a fetch:所以基本上我们有实体A,主要实体,和一些嵌套实体B,我们从A select,但想按B订购,并且在生成的sql中它只从A中选择列。我发现使它工作的唯一方法(=也从 B 使它成为 select )是用获取替换连接:

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

that worked for some time, was testing locally in H2, but then after some time started getting another error:工作了一段时间,在 H2 本地测试,但过了一段时间开始出现另一个错误:

org.hibernate.QueryException: query specified join fetching, but the owner of the fetched association was not present in the select list org.hibernate.QueryException:查询指定连接提取,但提取关联的所有者不在 select 列表中

I solved it somehow in my local pointing to H2 by requiring some columns to not be null, but in real server using PostgreSQL, it's not working at all, getting that error for all cases when a fetch is present.我通过要求某些列不是 null,但在使用 PostgreSQL 的真实服务器中,以某种方式在指向 H2 的本地解决了它,它根本不起作用,在存在提取的所有情况下都会出现该错误。

My question is: what is the right way to use distinct along with orderby on a nested entity that is not fetched?我的问题是:在未获取的嵌套实体上使用distinctorderby的正确方法是什么? Is my solution with fetch ok and it just needs to be fixed (and if so how?) or I should go for another option entirely?我的fetch解决方案是否正常,只需要修复(如果是的话如何修复?)或者我应该 go 完全用于另一个选项?

For the actual query I am using this method:对于实际查询,我使用这种方法:

findAll(Specification<>, Pageable)

Isn't there a way to have distinct wrapping the whole query with order by (some sort of subquery?) and bypassing all this nightmare?有没有办法用 order by (某种子查询?)来独特地包装整个查询并绕过所有这些噩梦? Have it generate a query like this:让它生成这样的查询:

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

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

Do I need to convert my specification to predicate manually and do something else with it to try to solve my issues (some kind of hybrid approach)?我是否需要手动将我的规范转换为谓词并用它做其他事情来尝试解决我的问题(某种混合方法)?

Any pieces of advice will be greatly appreciated.任何建议将不胜感激。

I encountered same error but actually it was not error:)我遇到了同样的错误,但实际上它不是错误:)

findAll(Specification<>, Pageable) this method throws 2 different queries. findAll(Specification<>, Pageable) 这个方法抛出 2 个不同的查询。

First one is count query where you have to be careful.第一个是计数查询,您必须小心。 Second is the rows query where you actually did it.其次是您实际执行的行查询。

You can check the query type with code below您可以使用下面的代码检查查询类型

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM