Добавление списка предложений IN в запрос JPA

125

Я создал NamedQuery, который выглядит так:

@NamedQuery(name = "EventLog.viewDatesInclude",
        query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND "
        + "el.timeMark <= :dateTo AND "
        + "el.name IN (:inclList)")

Я хочу заполнить параметр: inclList списком элементов вместо одного элемента. Например, если у меня есть, new List<String>() { "a", "b", "c" }как мне получить это в параметре: inclList? Это позволяет мне кодировать только одну строку. Например:

setParameter("inclList", "a") // works

setParameter("inclList", "a, b") // does not work

setParameter("inclList", "'a', 'b'") // does not work

setParameter("inclList", list) // throws an exception

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

Связанный вопрос: если список очень большой, есть ли хороший способ создания такого запроса?

AlanObject
источник
Это дубликат stackoverflow.com/questions/1557085/…, но этот поток дает полезные ответы.
Майк Райан

Ответы:

182

При использовании INс параметром, оценивающим коллекцию, вам не нужны (...):

@NamedQuery(name = "EventLog.viewDatesInclude", 
    query = "SELECT el FROM EventLog el WHERE el.timeMark >= :dateFrom AND " 
    + "el.timeMark <= :dateTo AND " 
    + "el.name IN :inclList") 
axtavt
источник
6
Нет ... В моем случае все наоборот. Если я использую: inclList, он не работает. Если я использую IN (: inclList), он работает.
Gunjan Shah
1
Также обратите внимание на упоминание: тип вашего параметра должен быть коллекцией (а не массивом) объектов. Объекты должны соответствовать типу поля. .toString () не заменяет class String
dube
2
Я думаю, что это кое-что, что изменилось с версиями Hibernate, насколько я помню, я получил ошибку, когда при использовании IN не было парантезы вокруг переменной. Странно, если это не обратная совместимость ..
Тобб
1
Это действительно была ошибка гибернации (необходимость в скобках), которая была исправлена ​​в версии 3.6.1
Mat
1
На связанный вопрос: в случае очень большого списка могут быть ограничения для реализации. Например, оракул 11г. Максимум. Возможны 1000 элементов списка в качестве параметра. Обходной путь - разделить список на подсписки и собрать результаты. Сам JPA не ограничивает размер списка.
Mahttias Schrebiér
81

Правильный формат запроса JPA будет:

el.name IN :inclList

Если вы используете старую версию Hibernate в качестве провайдера, вам необходимо написать:

el.name IN (:inclList)

но это ошибка ( HHH-5126 ) (РЕДАКТИРОВАТЬ: которая уже решена).

Хосе Феррер
источник
5
Спасибо за то, что вы отличаетесь от более старых версий Hibernate use ()
Роб Л.
32
public List<DealInfo> getDealInfos(List<String> dealIds) {
        String queryStr = "SELECT NEW com.admin.entity.DealInfo(deal.url, deal.url, deal.url, deal.url, deal.price, deal.value) " + "FROM Deal AS deal where deal.id in :inclList";
        TypedQuery<DealInfo> query = em.createQuery(queryStr, DealInfo.class);
        query.setParameter("inclList", dealIds);
        return query.getResultList();
    }

У меня работает с JPA 2, Jboss 7.0.2

user1114134
источник
9

Вы должны преобразовать в, Listкак показано ниже:

    String[] valores = hierarquia.split(".");       
    List<String> lista =  Arrays.asList(valores);

    String jpqlQuery = "SELECT a " +
            "FROM AcessoScr a " +
            "WHERE a.scr IN :param ";

    Query query = getEntityManager().createQuery(jpqlQuery, AcessoScr.class);                   
    query.setParameter("param", lista);     
    List<AcessoScr> acessos = query.getResultList();
Уэсли Роча
источник
Спасибо, этот ответ мне помог
cabaji99 01