在这种情况下,如何使用DISTINCT创建休眠标准

时间:2013-06-26 06:59:33

标签: java spring hibernate jpa postgresql-9.2

我正在使用hibernate条件来创建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;

  3. 所以对于修复,我更喜欢hibernate方面的解决方案。如何创建一个标准,以便我可以获得上述两个平方中的任何一个。

    • 如何创建标准以获得嵌套选择。

    • 如何从条件中确保必须在select中应用按顺序使用的函数

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

    提前感谢您的建议。

1 个答案:

答案 0 :(得分: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”。