Спящий режим с нулями

Спящий режим, используемый с DB PostgreSQL при заказе desc в столбце, ставит нулевые значения выше, чем не null.

Стандарт SQL99 предлагает ключевое слово «NULLS LAST», чтобы объявить, что нулевые значения следует помещать ниже, чем не null.

Может ли поведение «NULLS LAST» быть достигнуто с использованием API критериев Hibernate?

Учитывая, что HHH-465 не фиксирован и не собирается исправляться в ближайшем будущем по причинам, указанным Стивом Эберсолем, лучшим вариантом будет использование CustomNullsFirstInterceptor прикрепленного к проблеме, либо глобально, либо специально для изменения инструкции SQL.

Я размещаю его ниже для читателей (кредиты Эмилио Дольче):

 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 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); } } 

Эта функция была реализована во время выпусков Hibernate 4.2.x и 4.3.x, как упоминалось ранее.

Его можно использовать, например:

 Criteria criteria = ...; criteria.addOrder( Order.desc( "name" ).nulls(NullPrecedence.FIRST) ); 

Hibernate v4.3 javadocs здесь меньше.

Вы можете настроить «nulls first» / «nulls last» в свойствах hibernate, чтобы по умолчанию был выбран любой критерий: hibernate.order_by.default_null_ordering=last (или =first ).

Подробнее см. Это hibernate commit .

Вот мое обновление для classа (Pascal Thivent):

 for (int i = 0; i < orderByNames.length; i++) { if (orderByNames[i].trim().length() > 0) { String orderName = orderByNames[i].trim().toLowerCase(); if (orderName.contains("desc")) { orderByNames[i] = orderName.replace("desc", "desc NULLS LAST"); } else { orderByNames[i] = orderName.replace("asc", "asc NULLS FIRST"); } } } 

Это устраняет проблему:

Это сломается, если sql имеет лимит / смещение после заказа – Sathish Apr 1 ’11 в 14:52

Также вы можете использовать это в JPA (hibernate):

 Session session = entityManager.unwrap(Session.class); Session nullsSortingProperlySession = null; try { // perform a query guaranteeing that nulls will sort last nullsSortingProperlySession = session.getSessionFactory().withOptions() .interceptor(new GuaranteeNullsFirstInterceptor()) .openSession(); } finally { // release the session, or the db connections will spiral try { if (nullsSortingProperlySession != null) { nullsSortingProperlySession.close(); } } catch (Exception e) { logger.error("Error closing session", e); } } 

Я тестировал это на postgres, и он исправляет ошибки «nulls are more than non-nulls», которые у нас были.

Другой вариант, если вы создаете SQL «на лету» и не используете Criteria API:

ORDER BY COALESCE (, ‘0’) [ASC | DESC]

Это работает либо для varchar, либо для числовых столбцов.

Кажется, что для этого открыт запрос на изменение / ошибка

  • Hibernate Named Query Order По параметру
  • Возврат результатов запроса в предопределенный порядок
  • Сравнение C # и OrderBy
  • Пользовательская логика сортировки в OrderBy с использованием LINQ
  • Множественный «порядок по» в LINQ
  • Выберите 3 последних записей, в которых значения одного столбца отличаются
  • Медленный запрос при использовании ORDER BY
  • Сортировка столбца строки, содержащего числа в SQL?
  • Как SQL Server сортирует ваши данные?
  • MySQL: Сортировка значений GROUP_CONCAT
  • LINQ Orderby Descending Query
  • Давайте будем гением компьютера.