Может ли javax.persistence.Query.getResultList () вернуть значение null?

115

И если да, то при каких обстоятельствах?

Спецификация Javadoc и JPA ничего не говорит.

rdk
источник
Я искал именно этот вопрос! спасибо! up 4 you!
rafa.ferreira 02

Ответы:

69

Ты прав. Спецификация JPA ничего об этом не говорит. Но книга Java Persistence with Hibernate, 2-е издание , говорит:

Если результат запроса пуст, возвращается ноль

Реализация Hibernate JPA (Entity Manager) возвращает null, когда вы вызываете query.getResultList () без результата.

ОБНОВИТЬ

Как отмечают некоторые пользователи, кажется, что новейшая версия Hibernate вместо этого возвращает пустой список.

Пустой список также возвращается в Eclipselink, если результаты не найдены.

Артур Рональд
источник
29
Это определенно устарело, Hibernate возвращает пустой список.
Майкл Лаффарг
2
Я все еще получаю null из Hibernate 4.3.10 (работающего как движок JPA для Spring Data). Это происходит только для одного собственного запроса, поскольку типичные запросы JPA работают должным образом.
Jacek Prucia
1
Просто проверьте оба условия с помощью ИЛИ. if(rows == null || rows.size == 0){}где строки - это то, что возвращает getResultList ()
Number945,
Просто оберните его в Optional.ofNullable (), и все готово.
de.la.ru
Я считаю, что возвращение nullвместо пустого списка - это не то, что предусмотрено спецификацией, поскольку в противном случае совершенно ясно, когда ожидать nullв других местах. Тем более что документация для getResultListчтения Execute a SELECT query and return the query results as a(n) (un)typed List. - @return a list of the results. Я все равно проверю, nullконечно, и сам верну пустой список, если нужно.
René
23

Если бы в спецификациях говорилось, что этого не может быть, вы бы поверили им? Учитывая, что ваш код предположительно может работать с различными реализациями JPA, доверяете ли вы каждому разработчику, который сделает это правильно?

Несмотря ни на что, я бы написал защитный код и проверил значение null.

Теперь большой вопрос: следует ли рассматривать «нуль» и пустой список как синонимы? Здесь спецификации должны нам помочь, а не нет.

Я предполагаю, что нулевой возврат (если это действительно может произойти) будет эквивалентен «Я не понял запрос», а пустой список будет «да, понял запрос, но не было записей».

Возможно, у вас есть кодовый путь (вероятно, исключение), который имеет дело с неразборчивыми запросами, я бы предпочел направить нулевой возврат по этому пути.

DJNA
источник
+1 Вы так правы, когда говорите: "Вы бы доверяли каждому провайдеру JPA?" НЕТ :)
dfa
Отредактировано для добавления: Артур указал, что JPA Hibernate на самом деле возвращает null, если записи не найдены. Фактически, в этом случае нам действительно нужно сложить пустой и пустой список. Я считаю, что мыслительный процесс, который мы прошли выше, все еще в силе. Возможно даже, что у нас должны быть разные обработки null для разных стеков JPA. Добро пожаловать в мир портативных игр.
djna
Согласовано. Существует только "забавная переносимость" из-за того, что спецификация JPA не выполняет то, что должна делать ... указать точную семантику. Жаль, что им управляет комитет с корыстными интересами.
DataNucleus
2
«Я не понял запрос» следует рассматривать, так как Exceptionвозвращение, nullгде Collectionнаходится в возвращаемом типе, является очевидным недостатком дизайна
Матони
13

Вопреки сообщению Артура, когда я действительно выполнил запрос, по которому не было найдено ни одного объекта, я получил пустой список, а не null. Здесь используется Hibernate, и это то, что я считаю правильным поведением: пустой список - это правильный ответ, когда вы запрашиваете набор сущностей, а их нет.

Эндрю Саймонс
источник
2
для OpenJPA я также получаю пустой список вместо нуля.
Gnavvy
3

Если вы внимательно посмотрите на org.hibernate.loader.Loader(4.1), вы увидите, что список всегда инициализируется внутри метода processResultSet () ( doc , source ).

protected List processResultSet(...) throws SQLException {
   final List results = new ArrayList();

   handleEmptyCollections( queryParameters.getCollectionKeys(), rs, session );
   ...
   return results;

}

Поэтому я не думаю, что сейчас он вернет null.

Чарльз Фолле
источник
2
Приветствую вас за точный фрагмент кода. Но этот ответ сосредоточен только на спящем режиме, который является одной из реализаций спецификации. Другие реализации, такие как OpenJPA, отличаются своим поведением. Кроме того, похоже, что спящий режим изменил поведение в разных версиях.
Venky
1

Конечно, если вы протестируете набор результатов с помощью Jakarta's CollectionUtils.isNotEmpty, вы в любом случае будете защищены.

Аль Шерер
источник
0

Query.getResultList()возвращает пустой список вместо null. Так что проверьте isEmpty()возвращенный результат и продолжите остальную логику, если он ложный.

Сирил Соян
источник
0

Учитывая реализацию getResultsList()in org.hibernate.ejb.QueryImplclass, можно вернуть null:

public List getResultList() {
    try {
        return query.list();
    }
    catch (QueryExecutionRequestException he) {
        throw new IllegalStateException(he);
    }
    catch( TypeMismatchException e ) {
        throw new IllegalArgumentException(e);
    }
    catch (HibernateException he) {
        em.throwPersistenceException( he );
        return null;
    }

Моя версия гибернации: 3.3.1.GA

хитрый койот
источник