Вы можете использовать json_decode () для преобразования строки json в объект / массив PHP.
Например.
Вход:
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
var_dump(json_decode($json, true));
Выход:
object(stdClass)#1 (5) {
["a"] => int(1)
["b"] => int(2)
["c"] => int(3)
["d"] => int(4)
["e"] => int(5)
}
array(5) {
["a"] => int(1)
["b"] => int(2)
["c"] => int(3)
["d"] => int(4)
["e"] => int(5)
}
Несколько точек для запоминания:
json_decode
требует, чтобы строка была действительной json
, иначе она вернется NULL
. json_last_error()
можно использовать для определения точного характера ошибки. utf8
контент, или json_decode
может выйти из строя и просто вернуть значение NULL
. Использование @SuppressWarnings
везде, как было предложено, является хорошим способом сделать это, хотя при этом каждый раз вы вызываете q.list()
. 'd suggest:
Collections.checkedList()
Замените свое назначение следующим образом:
List<Cat> cats = Collections.checkedList(q.list(), Cat.class);
Вы можете проверить javadoc для этого метода , особенно в отношении equals
и hashCode
.
Напишите хэндл-бросок
Просто рефакторируйте все ваши @SuppressWarnings
в одном месте:
List<Cat> cats = MyHibernateUtils.listAndCast(q);
...
public static <T> List<T> listAndCast(Query q) {
@SuppressWarnings("unchecked")
List list = q.list();
return list;
}
Предотвратить появление Eclipse для предупреждений о неизбежных проблемах
В Eclipse перейдите в «Окно»> «Настройки»> «Java»> «Компилятор»> «Ошибки / предупреждения» и в «Тип общего типа» установите флажок Ignore unavoidable generic type problems due to raw APIs
Это отключит ненужные предупреждения для подобных проблем, подобных описанным выше, которые неизбежны.
Некоторые комментарии:
Query
вместо результата q.list()
, потому что таким образом этот метод «обмана» может использоваться только для обмана с помощью Hibernate, а не для обмана любого List
i n. .iterate()
и т. д. Прошло много времени с тех пор, как был задан вопрос, но я надеюсь, что мой ответ может быть полезен кому-то вроде меня.
Если вы посмотрите на javax.persistence api docs , вы увидите, что с Java Persistence 2.0
добавлены некоторые новые методы. Один из них - createQuery(String, Class<T>)
, который возвращает TypedQuery<T>
. Вы можете использовать TypedQuery
так же, как вы это сделали с Query
с той небольшой разницей, что все операции теперь безопасны по типу.
Итак, просто измените свой код на smth следующим образом:
Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();
И вы все настроены.
Попробуйте следующее:
Query q = sess.createQuery("from Cat cat");
List<?> results = q.list();
for (Object obj : results) {
Cat cat = (Cat) obj;
}
cat
.
– Artjom B.
15 July 2014 в 23:19
По-видимому, метод Query.list () в Hibernate API не безопасен по типу «по дизайну», и не планирует его изменять .
Я считаю, что самым простым решением избежать предупреждений компилятора действительно является добавление @SuppressWarnings («unchecked»). Эта аннотация может быть помещена на уровне метода или, если внутри метода, прямо перед объявлением переменной.
Если у вас есть метод, который инкапсулирует Query.list () и возвращает List (или Collection), вы также получите предупреждение. Но это подавляется с помощью @SuppressWarnings («rawtypes»).
Метод ListAndCast (Query), предложенный Matt Quail, менее гибок, чем Query.list (). Хотя я могу сделать:
Query q = sess.createQuery("from Cat cat");
ArrayList cats = q.list();
Если я попробую код ниже:
Query q = sess.createQuery("from Cat cat");
ArrayList<Cat> cats = MyHibernateUtils.listAndCast(q);
Я получу ошибку компиляции: Несоответствие типа: невозможно преобразовать из списка к ArrayList
Мы также используем @SuppressWarnings("unchecked")
, но мы чаще всего пытаемся использовать его только при объявлении переменной, а не в методе в целом:
public List<Cat> findAll() {
Query q = sess.createQuery("from Cat cat");
@SuppressWarnings("unchecked")
List<Cat> cats = q.list();
return cats;
}
Попробуйте использовать TypedQuery
вместо Query
. Например, вместо этого: -
Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();
Используйте это: -
TypedQuery<Cat> q1 = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q1.list();
Нет, но вы можете выделить его в конкретные методы запроса и подавить предупреждения с помощью аннотации @SuppressWarnings("unchecked")
.
Новые версии Hibernate теперь поддерживают безопасный тип Query<T>
, поэтому вам больше не нужно использовать @SuppressWarnings
или реализовать какой-либо взломать, чтобы предупреждения компилятора исчезли. В Session API , Session.createQuery
теперь вернет объект типа safe Query<T>
. Вы можете использовать его следующим образом:
Query<Cat> query = session.createQuery("FROM Cat", Cat.class);
List<Cat> cats = query.list();
Вы также можете использовать его, когда результат запроса не вернет Cat:
public Integer count() {
Query<Integer> query = sessionFactory.getCurrentSession().createQuery("SELECT COUNT(id) FROM Cat", Integer.class);
return query.getSingleResult();
}
или при частичном выборе:
public List<Object[]> String getName() {
Query<Object[]> query = sessionFactory.getCurrentSession().createQuery("SELECT id, name FROM Cat", Object[].class);
return query.list();
}
Я знаю, что это старше, но 2 пункта, чтобы отметить на сегодняшний день в ответе Matt Quails.
Это
List<Cat> cats = Collections.checkedList(Cat.class, q.list());
Должно быть это
List<Cat> cats = Collections.checkedList(q.list(), Cat.class);
Из этого
List list = q.list();
к этому
List<T> list = q.list();
будут уменьшены другие предупреждения, очевидно, в оригинальные метки тега ответа были удалены браузером.
Если вы не хотите использовать @SuppressWarnings («unchecked»), вы можете сделать следующее.
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 - я создал метод утилиты, который делает это для меня, я не могу использовать мой код, и мне не нужно использовать @SupressWarning.
У нас была такая же проблема. Но это было не очень важно для нас, потому что нам пришлось решать другие более серьезные проблемы с помощью Hibernate Query и Session.
В частности:
Итак, для нас мы имеем:
И, наконец,
AmplafiQuery имеет «asList ()», который является универсальной версией Query.list () У AmplafiQuery есть «unique ()», который является универсальной версией Query.uniqueRe sult () (и просто регистрирует проблему, а не бросает исключение)
Это большая работа, чтобы просто избежать @SuppressWarnings. Однако, как я уже сказал (и перечислены), есть много других лучше! причины для выполнения работ по упаковке.
Это не недосмотр или ошибка. Предупреждение отражает реальную основную проблему - нет никакого способа, чтобы java-компилятор действительно мог убедиться, что класс hibernate будет выполнять свою работу должным образом и что список, который он возвращает, будет содержать только Cats. Любое из предложений здесь в порядке.
Решение Joe Dean выглядит интересным, но вы думаете, что это того стоит - создайте новый List и пропустите все элементы, чтобы избавиться от предупреждений?
(извините, не могу добавить комментарий прямо к его решению по какой-то причине)
В нашем коде мы аннотируем вызывающие методы с помощью:
@SuppressWarnings («unchecked»)
Я знаю, что это похоже на взломать, но недавно был проверен со-разработчик и что это все, что мы могли бы сделать.
Хорошее решение, чтобы избежать предупреждений о безопасности типа с запросом на спящий режим, - использовать инструмент, например TorpedoQuery , чтобы помочь вам построить безопасный тип hql.
Cat cat = from(Cat.class);
org.torpedoquery.jpa.Query<Entity> select = select(cat);
List<Cat> cats = select.list(entityManager);
Collections.checkedList()
не будет отменять предупреждение о непроверенной задаче. – Diablo 9 September 2016 в 12:55