3

我正在使用休眠条件来创建 postgres 查询:

criteria.addOrder(Order.asc(property).ignoreCase()).setProjection(
                            Projections.distinct(Projections.property("name")));

生成类似于下面的sql:

select DISTINCT name from table1 order by lower( name) asc;

当这个 sql 被执行时,会出现以下错误:

ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list

我知道这违反了 postgres 规则,但是当我查看错误时,我发现我们不应该在 order by 子句中使用任何函数。如果使用它,那么我们需要有两个解决方法:

  1. 使用嵌套选择如下:

    select name from (select distinct name from table1) as aliasname order by lower(name) asc;

  2. 在 select 和 order by 子句中都使用 lower 函数。

    select DISTINCT lower(name) from table1 order by lower(name) asc;

因此,对于修复,我更喜欢休眠方面的解决方案。如何创建一个标准,以便我可以获得上述两个 sql 中的任何一个。

  • 如何创建条件以获取嵌套选择。

  • 如何从标准中确保按顺序使用的功能也必须在选择中应用

    • 在休眠或数据库方面有没有更好的解决方案(不使用硬编码的 sql、createQuery() 或 HQL)。

提前感谢您的建议。

4

1 回答 1

1

我最近遇到了同样的问题并最终使用SQLProjection。我意识到这篇文章已经有几年的历史了,但我还没有找到任何其他帖子的解决方案可以工作或不需要用硬编码的 sql 重写整个查询,所以希望这会帮助遇到这个问题的其他人问题。这个解决方案仍然需要一些硬编码的 sql,但它是最小的。

String[] columnAlias = {"name"};
criteria.addOrder(Order.asc("name").ignoreCase()).setProjection(Projections.distinct(
Projections.sqlProjection("lower(" + criteria.alias + "_.name) as name", columnAlias,
Hibernate.STRING as Type[])));

这应该产生以下 sql:

select distinct lower(this_.name) as name from table1 this_ order by lower(this_.name) asc;

注意:除非另有说明,否则criteria.alias默认设置为“this”。

于 2016-03-05T00:35:32.923 回答