Czy javax.persistence.Query.getResultList () może zwrócić wartość null?

115

A jeśli tak, w jakich okolicznościach?

Specyfikacja Javadoc i JPA nic nie mówi.

rdk
źródło
Szukałem dokładnie tego pytania! tks! do 4 Ciebie!
rafa.ferreira

Odpowiedzi:

69

Masz rację. Specyfikacja JPA nic o tym nie mówi. Ale Java Persistence with Hibernate book, 2nd edition , mówi:

Jeśli wynik zapytania jest pusty, zwracana jest wartość null

Implementacja Hibernate JPA (Entity Manager) zwraca wartość null, gdy wywołasz query.getResultList () bez wyniku.

AKTUALIZACJA

Jak zauważyli niektórzy użytkownicy, wydaje się, że najnowsza wersja Hibernate zwraca zamiast tego pustą listę.

W przypadku braku wyników zwracana jest również pusta lista w Eclipselink.

Arthur Ronald
źródło
29
Jest to z pewnością nieaktualne, Hibernate zwraca pustą listę.
Michael Laffargue
2
Nadal otrzymuję wartość null z Hibernate 4.3.10 (działającego jako silnik JPA dla Spring Data). Dzieje się tak tylko w przypadku pojedynczego zapytania natywnego, ponieważ typowe zapytania JPA działają zgodnie z oczekiwaniami.
Jacek Prucia 25.06.2015
1
Po prostu sprawdź oba warunki za pomocą OR. if(rows == null || rows.size == 0){}gdzie wiersze są tym, co zwraca getResultList ()
Number945
Po prostu zawiń go w parametr Optional.ofNullable () i gotowe.
de.la.ru
Uważam, że powrót nullzamiast pustej listy nie jest tym, co jest zamierzone w specyfikacji, ponieważ w przeciwnym razie jasno określa, kiedy można się spodziewać nullw innych miejscach. Zwłaszcza, że ​​dokumentacja do getResultListreads Execute a SELECT query and return the query results as a(n) (un)typed List. - @return a list of the results. nullOczywiście nadal sprawdzałem i w razie potrzeby zwracałem pustą listę.
René
23

Gdyby specyfikacje mówiły, że to się nie może zdarzyć, uwierzyłbyś im? Biorąc pod uwagę, że Twój kod mógłby prawdopodobnie działać przeciwko różnym implementacjom JPA, czy ufasz każdemu wdrażającemu, że zrobi to dobrze?

Bez względu na wszystko, koduję defensywnie i sprawdzam, czy nie ma wartości null.

Teraz najważniejsze pytanie: czy „null” i pusta lista powinniśmy traktować jako synonimy? W tym przypadku specyfikacja powinna nam pomóc, a nie.

Domyślam się, że zwrot zerowy (jeśli rzeczywiście może się zdarzyć) byłby równoważny z „Nie zrozumiałem zapytania”, a pusta lista byłaby „tak, zrozumiałem zapytanie, ale nie było żadnych rekordów”.

Być może masz ścieżkę kodu (prawdopodobnie wyjątek), która zajmuje się zapytaniami, których nie można przeanalizować, miałbym tendencję do kierowania zerowego powrotu w dół tej ścieżki.

djna
źródło
+1 masz rację, mówiąc: „czy zaufałbyś każdemu dostawcy JPA?” NIE :)
dfa
Zredagowane, aby dodać: Arthur wskazał, że JPA Hibernate w rzeczywistości zwraca wartość null, jeśli nie znaleziono żadnych rekordów. Więc w rzeczywistości w tym przypadku musimy złożyć razem pustą listę. Uważam, że proces myślowy, który przeszliśmy powyżej, jest nadal aktualny. Można nawet sobie wyobrazić, że powinniśmy mieć różne sposoby traktowania wartości zerowej dla różnych stosów JPA. Witamy w zabawie z przenośnością.
djna
Zgoda. Istnieje tylko „zabawa z przenoszeniem”, ponieważ specyfikacja JPA nie robi tego, co powinna… określić dokładną semantykę. Szkoda, że ​​jest zarządzany przez komitet z osobnymi interesami.
DataNucleus
2
„Nie rozumiem zapytania” powinno być traktowane jako Exception, że zwracanie nullgdzie Collectionjest w zwracanym typie jest oczywistą wadą projektową
matoni
13

W przeciwieństwie do posta Arthura, kiedy faktycznie wykonałem zapytanie, do którego nie pasowały żadne jednostki, otrzymałem pustą listę, a nie null. To używa Hibernacji i uważam, że to jest właściwe zachowanie: pusta lista jest poprawną odpowiedzią, gdy pytasz o kolekcję jednostek, a nie ma żadnych.

Andrew Simons
źródło
2
w przypadku OpenJPA otrzymuję również pustą listę zamiast wartości null.
Gnavvy,
3

Jeśli przyjrzysz się bliżej org.hibernate.loader.Loader(4.1), zobaczysz, że lista jest zawsze inicjalizowana wewnątrz metody processResultSet () ( doc , source ).

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

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

}

Więc nie sądzę, że teraz zwróci zero.

Charles Follet
źródło
2
Pozdrawiam za dokładny fragment kodu. Ale ta odpowiedź skupia się tylko na hibernacji, która jest jedną z implementacji specyfikacji. Inne implementacje, takie jak OpenJPA, różnią się zachowaniem. Wydaje się również, że hibernacja zmieniła zachowanie w różnych wersjach.
venky
1

Oczywiście, jeśli przetestujesz zestaw wyników za pomocą CollectionUtils.isNotEmpty firmy Jakarta, jesteś objęty i tak.

Al Scherer
źródło
0

Query.getResultList()zwraca pustą listę zamiast null. Więc sprawdź isEmpty()zwrócony wynik i kontynuuj resztę logiki, jeśli jest fałszywa.

Cyril Sojan
źródło
0

Biorąc pod uwagę implementację getResultsList()w org.hibernate.ejb.QueryImplklasie, można zwrócić 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;
    }

Moja wersja hibernacji to: 3.3.1.GA

podstępny kojot
źródło