Jak uniknąć ostrzeżeń o bezpieczeństwie typu z wynikami Hibernate HQL?
Na przykład mam takie zapytanie:
Query q = sess.createQuery("from Cat cat");
List cats = q.list();
Jeśli spróbuję zrobić coś takiego, wyświetli się Ostrzeżenie "bezpieczeństwo typu: wyrażenie listy typów wymaga niezaznaczonej konwersji, aby było zgodne z listą":
List<Cat> cats = q.list();
Czy jest sposób, aby tego uniknąć?
16 answers
Używanie @SuppressWarnings
wszędzie, zgodnie z sugestią, jest dobrym sposobem, aby to zrobić, chociaż wymaga to odrobiny pisania palcem za każdym razem, gdy dzwonisz q.list()
.
Są trzy inne techniki, które proponuję:
Collections.checkedList()
Zamień swoje zadanie na to:
List<Cat> cats = Collections.checkedList(q.list(), Cat.class);
Możesz sprawdzić javadoc dla tej metody , szczególnie w odniesieniu do equals
i hashCode
.
Napisz cast-helper
Po prostu refaktoruj wszystkie swoje @SuppressWarnings
w jednym miejscu:
List<Cat> cats = MyHibernateUtils.listAndCast(q);
...
public static <T> List<T> listAndCast(Query q) {
@SuppressWarnings("unchecked")
List list = q.list();
return list;
}
Uniemożliwić Eclipse generowanie ostrzeżeń o nieuniknionych problemach
W Eclipse, przejdź do Window>Preferences>Java>Compiler>Errors / Warnings i w obszarze Generic type wybierz checkbox
Ignore unavoidable generic type problems due to raw APIs
Spowoduje to wyłączenie niepotrzebnych ostrzeżeń o podobnych problemach, takich jak opisany powyżej, które są nieuniknione.
Kilka komentarzy:
- wybrałem zdanie
Query
zamiast wynikuq.list()
ponieważ w ten sposób ta metoda "oszukiwania" może być używana tylko do oszukiwania z Hibernate, a nie do oszukiwania jakichkolwiekList
w ogóle. - możesz dodać podobne metody dla
.iterate()
itp.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-01 09:35:13
Minęło sporo czasu odkąd zadano pytanie, ale mam nadzieję, że moja odpowiedź może być pomocna dla kogoś takiego jak ja.
Jeśli spojrzysz na javaxa.persistence API docs , zobaczysz, że niektóre nowe metody zostały tam dodane odJava Persistence 2.0
. Jednym z nich jest createQuery(String, Class<T>)
, który zwraca TypedQuery<T>
. Możesz użyć TypedQuery
tak jak to zrobiłeś z Query
z tą małą różnicą, że wszystkie operacje są teraz bezpieczne.
Więc po prostu zmień swój kod na smth w ten sposób:
Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();
I ty wszystko gotowe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-15 20:24:00
Używamy również @SuppressWarnings("unchecked")
, ale najczęściej staramy się go używać tylko na deklaracji zmiennej, a nie na metodzie jako całości:
public List<Cat> findAll() {
Query q = sess.createQuery("from Cat cat");
@SuppressWarnings("unchecked")
List<Cat> cats = q.list();
return cats;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 16:55:18
Spróbuj użyć TypedQuery
zamiast Query
.
Na przykład zamiast tego: -
Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();
Użyj tego:-
TypedQuery<Cat> q1 = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q1.list();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-05 12:28:16
W naszym kodzie opisujemy metody wywołujące za pomocą:
@ SuppressWarnings ("unchecked")
Wiem, że to wygląda na włamanie, ale współtwórca sprawdził niedawno i stwierdził, że to wszystko, co mogliśmy zrobić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 15:57:42
Najwyraźniej, zapytanie.metoda list () w API Hibernate nie jest bezpieczna dla typu "z założenia" i nie ma planów jej zmiany.
Uważam, że najprostszym rozwiązaniem, aby uniknąć ostrzeżeń kompilatora, jest dodanie @SuppressWarnings ("unchecked"). Ta adnotacja może być umieszczona na poziomie metody lub, jeśli wewnątrz metody, tuż przed deklaracją zmiennej.
W przypadku, gdy masz metodę, która enkapsuluje zapytanie.list () i returns List (lub Collection), otrzymujesz również Ostrzeżenie. Ale ten jest tłumiony za pomocą @SuppressWarnings ("rawtypes").
Metoda listAndCast (zapytanie) zaproponowana przez Matta przepiórki jest mniej elastyczna niż zapytanie.list(). While I can do:
Query q = sess.createQuery("from Cat cat");
ArrayList cats = q.list();
Jeśli wypróbuję poniższy kod:
Query q = sess.createQuery("from Cat cat");
ArrayList<Cat> cats = MyHibernateUtils.listAndCast(q);
Dostanę błąd kompilacji: type mismatch: cannot convert from List to ArrayList
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:39
To nie przeoczenie czy pomyłka. Ostrzeżenie odzwierciedla prawdziwy podstawowy problem - nie ma mowy, aby kompilator Javy mógł być pewien, że Klasa hibernate wykona swoją pracę prawidłowo i że lista, którą zwraca, będzie zawierała tylko koty. Wszelkie sugestie tutaj są w porządku.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-13 02:55:37
Nie, ale możesz wyodrębnić go w konkretne metody zapytań i wyłączyć ostrzeżenia za pomocą adnotacji @SuppressWarnings("unchecked")
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 15:58:50
Mieliśmy ten sam problem. Ale nie było to dla nas nic wielkiego, ponieważ musieliśmy rozwiązać inne bardziej poważne problemy z zapytaniem Hibernate i sesją.
Konkretnie:
- Kontrola, kiedy transakcja może zostać zrealizowana. (chcieliśmy policzyć ile razy tx został " uruchomiony "i zatwierdzić tylko wtedy, gdy tx został" zakończony " tyle samo razy, ile razy został uruchomiony. Przydatne dla kodu, który nie wie, czy trzeba rozpocząć transakcję. Teraz każdy kod, który potrzebuje tx po prostu "uruchamia" jeden i kończy go kiedy skończymy.)
- zbieranie metryk wydajności.
- opóźnianie rozpoczęcia transakcji, dopóki nie będzie wiadomo, że coś faktycznie zostanie zrobione.
- bardziej delikatne zachowanie dla zapytania.uniqueResult ()
Więc dla nas mamy:
- Tworzenie interfejsu (AmplafiQuery), który rozszerza zapytanie
- Utwórz klasę (AmplafiQueryImpl), która rozszerza AmplafiQuery i owija org.hibernacja.Query
- tworzy Txmanager, który zwraca Tx.
- Tx ma różne metody createQuery i zwraca AmplafiQueryImpl
I na koniec
AmplafiQuery ma "asList ()", która jest generyczną włączoną wersją zapytania.lista() AmplafiQuery posiada "unique ()", która jest generyczną włączoną wersją Query.uniqueResult() ( i tylko rejestruje problem zamiast rzucać wyjątek)
To dużo pracy na unikanie @ SuppressWarnings. Jednak, jak powiedziałem (I wymienione) jest wiele innych lepszych! powody, dla których warto wykonać pakowanie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-13 02:08:02
Nowsze wersje Hibernate obsługują teraz obiekt type safe Query<T>
, więc nie musisz już używać @SuppressWarnings
ani implementować hacków, aby ostrzeżenia kompilatora zniknęły. W API sesji , Session.createQuery
zwróci teraz obiekt type safe Query<T>
. Możesz go użyć w ten sposób:
Query<Cat> query = session.createQuery("FROM Cat", Cat.class);
List<Cat> cats = query.list();
Można go również użyć, gdy wynik zapytania nie zwróci kota:
public Integer count() {
Query<Integer> query = sessionFactory.getCurrentSession().createQuery("SELECT COUNT(id) FROM Cat", Integer.class);
return query.getSingleResult();
}
Lub podczas wykonywania częściowego wyboru:
public List<Object[]> String getName() {
Query<Object[]> query = sessionFactory.getCurrentSession().createQuery("SELECT id, name FROM Cat", Object[].class);
return query.list();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-07 15:11:27
Rozwiązanie Joe Deana wygląda ciekawie, ale czy uważasz, że warto-stworzyć nową listę i przebić się przez wszystkie elementy tylko po to, aby pozbyć się ostrzeżeń?
(sorry, can ' t add a comment directly to his solution for some reason)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 16:48:08
Wiem, że to jest starsze, ale 2 punkty do odnotowania na dzień dzisiejszy w Matt Quails odpowiedzi.
Punkt 1
To
List<Cat> cats = Collections.checkedList(Cat.class, q.list());
Powinno być to
List<Cat> cats = Collections.checkedList(q.list(), Cat.class);
Punkt 2
Z tego
List list = q.list();
Do tego
List<T> list = q.list();
Zmniejszyłoby inne ostrzeżenia, oczywiście w oryginalnych znacznikach odpowiedzi, które zostały usunięte przez przeglądarkę.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-01 23:56:35
Spróbuj tego:
Query q = sess.createQuery("from Cat cat");
List<?> results = q.list();
for (Object obj : results) {
Cat cat = (Cat) obj;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-15 21:53:05
Dobrym rozwiązaniem, aby uniknąć ostrzeżeń o bezpieczeństwie typu za pomocą zapytania hibernate, jest użycie narzędzia typu TorpedoQuery, które pomoże Ci zbudować bezpieczny Typ hql.
Cat cat = from(Cat.class);
org.torpedoquery.jpa.Query<Entity> select = select(cat);
List<Cat> cats = select.list(entityManager);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-11 18:54:00
TypedQuery<FDPCDRDetails> createQuery = entityManager.createQuery("from FDPCDRDetails", FDPCDRDetails.class);
List<FDPCDRDetails> resultList = createQuery.getResultList();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-17 05:56:26
Jeśli nie chcesz używać @SuppressWarnings ("unchecked"), możesz wykonać następujące czynności.
Query q = sess.createQuery("from Cat cat");
List<?> results =(List<?>) q.list();
List<Cat> cats = new ArrayList<Cat>();
for(Object result:results) {
Cat cat = (Cat) result;
cats.add(cat);
}
FYI-stworzyłem metodę util, która robi to za mnie, aby nie zaśmiecać mojego kodu i nie muszę używać @SupressWarning.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 16:34:04