Предложение JPQL IN: Java-массивы (или списки, наборы…)?

108

Я хотел бы загрузить все объекты, для которых текстовый тег установлен на любое небольшое, но произвольное количество значений из нашей базы данных. Логичным способом сделать это в SQL было бы создание предложения «IN». JPQL допускает IN, но, кажется, требует, чтобы я указывал каждый параметр для IN напрямую (например, "in (: in1,: in2,: in3)").

Есть ли способ указать массив или список (или какой-либо другой контейнер), который следует развернуть до значений предложения IN?

Бернд Хауг
источник

Ответы:

208

Я не уверен в JPA 1.0, но вы можете передать Collectionв JPA 2.0:

String qlString = "select item from Item item where item.name IN :names"; 
Query q = em.createQuery(qlString, Item.class);

List<String> names = Arrays.asList("foo", "bar");

q.setParameter("names", names);
List<Item> actual = q.getResultList();

assertNotNull(actual);
assertEquals(2, actual.size());

Протестировано с EclipseLInk. В Hibernate 3.5.1 вам нужно заключить параметр в круглые скобки:

String qlString = "select item from Item item where item.name IN (:names)";

Но это ошибка, запрос JPQL в предыдущем примере является допустимым JPQL. См. HHH-5126 .

Паскаль Тивент
источник
5
есть ли максимальное количество имен для использования в "in clause"?
Gondim
3
Вышеупомянутая ошибка в Hibernate, кажется, исправлена ​​в версии 3.6.1
Денис Княжев
1
@pringlesinn количество значений в предложении IN зависит от вашей СУБД
Тим Бют
работает в JPA 1.0 (и в нем нет обязательного заключения в круглые скобки, но для удобства чтения вы должны)
Хавьер Лариос
что, если вы хотите => item.name в (например: names)
dzgeek
3

Предел оракула - 1000 параметров. Проблема была решена с помощью спящего режима в версии 4.1.7, хотя путем разделения переданного списка параметров на наборы по 500 см. JIRA HHH-1123.

Ашиш Тукрал
источник
1
К сожалению, это не было решено. Запрос был отмечен как решенный, но проблема (как показано в комментариях) не была устранена командой Hibernate.
Druckles 06
@Druckles эм где? Я не вижу комментариев старше 2016 года. И это были только два комментария, в которых практически ничего не говорится, кроме обычного интернета: «Помогите, пожалуйста !!! 11 !!!!». Вы не дали никаких оснований полагать, что отчет об ошибке исправлен.
searchchengine27
@ searchchengine27 Я сказал, что отчет не был решен, несмотря на то, что он отмечен как решенный. Как сообщил Стив Эберсол, решение было таким: «Решение состоит в том, что мы просто собираемся предупреждать пользователей с помощью регистрации при обнаружении этого состояния». Комментарии Ноэля Траута еще в 2012 году подробно объясняют, почему этого недостаточно.
Druckles
Другими словами, это неверный ответ или, в лучшем случае, вводящий в заблуждение.
Druckles