Hibernate order by nulls last

mga*_*mer 33 java null hibernate sql-order-by

Hibernate与PostgreSQL DB一起使用,同时按列对desc进行排序会使空值高于非空值.

SQL99标准提供关键字"NULLS LAST"来声明空值应该低于非空值.

使用Hibernate的Criteria API可以实现"NULLS LAST"行为吗?

Jos*_*ias 47

如前所述,此功能已在Hibernate 4.2.x和4.3.x版本中实现.

它可以用作例如:

Criteria criteria = ...;
criteria.addOrder( Order.desc( "name" ).nulls(NullPrecedence.FIRST) );
Run Code Online (Sandbox Code Playgroud)

Hibernate v4.3 javadocs在这里不那么有用.


Pas*_*ent 16

鉴于HHH-465不是固定的,并且由于Steve Ebersole给出的原因不会在不久的将来得到修复,你最好的选择CustomNullsFirstInterceptor是全局或专门使用附加的问题来改变SQL语句.

我在下面为读者发布它(Emilio Dolce的作品):

public class CustomNullsFirstInterceptor extends EmptyInterceptor {

    private static final long serialVersionUID = -3156853534261313031L;

    private static final String ORDER_BY_TOKEN = "order by";

    public String onPrepareStatement(String sql) {

        int orderByStart = sql.toLowerCase().indexOf(ORDER_BY_TOKEN);
        if (orderByStart == -1) {
            return super.onPrepareStatement(sql);
        }
        orderByStart += ORDER_BY_TOKEN.length() + 1;
        int orderByEnd = sql.indexOf(")", orderByStart);
        if (orderByEnd == -1) {
            orderByEnd = sql.indexOf(" UNION ", orderByStart);
            if (orderByEnd == -1) {
                orderByEnd = sql.length();
            }
        }
        String orderByContent = sql.substring(orderByStart, orderByEnd);
        String[] orderByNames = orderByContent.split("\\,");
        for (int i=0; i<orderByNames.length; i++) {
            if (orderByNames[i].trim().length() > 0) {
                if (orderByNames[i].trim().toLowerCase().endsWith("desc")) {
                    orderByNames[i] += " NULLS LAST";
                } else {
                    orderByNames[i] += " NULLS FIRST";
                }
            }
        }
        orderByContent = StringUtils.join(orderByNames, ",");
        sql = sql.substring(0, orderByStart) + orderByContent + sql.substring(orderByEnd); 
        return super.onPrepareStatement(sql);
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 漂亮的解决方案,我没想过拦截器,谢谢!如果有人想要使用它,你需要将这一行添加到你的persistence.xml文件中:<property name ="hibernate.ejb.interceptor"value ="com.example.CustomNullsFirstInterceptor"/> (3认同)
  • 哇,Hibernate JIRA于2005年开放**** (3认同)
  • 看来HHH-465是用4.2版固定的(2013年3月) (2认同)

uwo*_*fer 8

您可以在hibernate属性中配置"nulls first"/"nulls last",因此默认情况下它将被任何条件调用拾取:( hibernate.order_by.default_null_ordering=last=first).

有关详细信息,请参阅此hibernate提交.