How to create hibernate criteria with DISTINCT in this case

拜拜、爱过 提交于 2019-12-07 13:08:28

问题


I am using hibernate criteria to create postgres query:

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

which generates sql similar to below:

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

and when this sql gets executed gives below error:

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

I know this is something against the postgres rule, but when i looked into the error, i found that we should not use any function at order by clause. If its used then we need to have two work arounds:

  1. use nested select as below:

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

  2. use lower function in both select and order by clause.

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

So for the fix, I will prefer a solution into hibernate side. how to create a criteria such that i can get any of the above two sqls.

  • how to create criteria to get nested select.

  • how ensure from criteria that the function used in order by must be applied in select also

    • is ther any better solution on hibernate or DB side (without using hardcoded sql, createQuery() or HQL).

thanks for your suggetions in advance.


回答1:


I recently ran into the same problem and ended up using SQLProjection. I realize that this post is a couple of years old, but I haven't found any other posts with solutions that either work or don't require rewriting the entire query with hardcoded sql, so hopefully this will help someone else who runs into this issue. This solution still requires some hardcoded sql, but it is minimal.

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[])));

This should produce the following sql:

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

Note: unless otherwise specified, criteria.alias is set to 'this' by default.



来源:https://stackoverflow.com/questions/17313502/how-to-create-hibernate-criteria-with-distinct-in-this-case

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!