Додавання списку пропозицій 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

Я знаю, що міг би просто побудувати рядок і створити з цього весь Запит, але хотів уникнути накладних витрат. Чи є кращий спосіб зробити це?

Пов’язане запитання: якщо Список дуже великий, чи існує якийсь хороший спосіб побудови запиту?


Це дублікат stackoverflow.com/questions/1557085/…, але ця тема дає корисні відповіді.
Майк Райан

Відповіді:


181

При використанні INз параметром, який оцінює колекцію, вам не потрібно (...):

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

6
Ні ... я мою справу навпаки. Якщо я використовую: inclList, то його не працює. Якщо я використовую IN (: inclList), він працює.
Гунян Шах

1
Також зауважте, що тип вашого параму повинен бути колекцією (а не масивом) об'єктів. Об'єкти повинні відповідати типу поля. .toString () не замінює клас String
дуб

2
Я думаю, що це щось змінилося з версіями Hibernate, наскільки я пам'ятаю, я отримав помилку, коли не мав парантезу навколо змінної при використанні IN. Дивно, якщо це не сумісність назад ..
Tobb

1
Це справді була сплячка помилка (потреба в дужках), яка була виправлена ​​в 3.6.1
Мат

1
Зв'язане питання: У випадку дуже великого переліку можуть бути обмеження щодо впровадження. Наприклад оракул 11г. макс. 1000 параметрів списку як параметр можливі. Вирішення завдання полягає в рубанні списку в підсписках та збиранні результатів. Сам JPA не обмежує розмір списку.
Махтіяс Шреб'єр

81

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

el.name IN :inclList

Якщо ви використовуєте старішу версію Hibernate як свого постачальника, вам потрібно написати:

el.name IN (:inclList)

але це помилка ( HHH-5126 ) (EDIT: яку вже вирішено).


5
Дякуємо вам за відмінність старих версій Hibernate use ()
Rob L

31
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


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();

Thx ця відповідь мені допомогла
cabaji99
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.