Выполнение запроса IN с помощью Hibernate - PullRequest
33 голосов
/ 27 июня 2010

У меня есть список идентификаторов в строке, и я хочу использовать Hibernate для получения строк с этими идентификаторами. TrackedItem является сущностью Hibernate / JPA (извините, если я перепутал названия).

Мой код:

String idsText = "380, 382, 386";
ArrayList<Long> ids = new ArrayList<Long>();

for (String i : idsText.split(","))
{
    ids.add(Long.getLong(i));
}

List<TrackedItem> items = TrackedItem.find("id IN (?)", ids).fetch();

Но это не удалось: JPAQueryException occured : Error while executing query from models.TrackedItem where id IN (?): java.util.ArrayList cannot be cast to java.lang.Long

Как мне заставить работать IN деталь? Спасибо.

Ответы [ 3 ]

60 голосов
/ 27 июня 2010

Синтаксис вашего запроса JPQL неверен. Либо использовать (с позиционным параметром):

List<Long> ids = Arrays.asList(380L, 382L, 386L);
Query query = em.createQuery("FROM TrackedItem item WHERE item.id IN (?1)");
query.setParameterList(1, ids)
List<TrackedItem> items = query.getResultList();

Или (с именованным параметром):

List<Long> ids = Arrays.asList(380L, 382L, 386L);
Query query = em.createQuery("FROM TrackedItem item WHERE item.id IN :ids");
query.setParameterList("ids", ids)
List<TrackedItem> items = query.getResultList();

Ниже приведены соответствующие разделы спецификации JPA 1.0 о параметрах:

4.6.4.1 Позиционные параметры

Следующие правила применяются к позиционным параметрам.

  • Входные параметры обозначаются префиксом вопросительного знака (?), За которым следует целое число. Например: ?1.
  • Входные параметры нумеруются, начиная с 1.
    Обратите внимание, что один и тот же параметр может использоваться более одного раза в строке запроса и что порядок использования параметров в строке запроса не должен соответствовать порядку позиционных параметров.

4.6.4.2 Именованные параметры

Именованный параметр - это идентификатор, перед которым стоит символ «:». Он следует правилам для идентификаторов, определенных в разделе 4.4.1. Именованные параметры чувствительны к регистру.

Пример: * * тысяча двадцать-восемь

SELECT c
FROM Customer c
WHERE c.status = :stat

Раздел 3.6.1 описывает API для привязки именованных параметров запроса

10 голосов
/ 13 апреля 2015

Если вам не повезло использовать более старый спящий режим не JPA, это должно работать для вас:

Query query = session.createQuery("FROM TrackedItem item WHERE item.id IN (:items)");
query.setParameterList("items", Arrays.asList(380L, 382L, 386L));

@SuppressWarnings("unchecked")
List<TrackedItem> results = query.list();
0 голосов
/ 12 февраля 2019

Даже если ваш запрос выполняется правильно, вы можете столкнуться с ошибкой, если ваш параметр запроса содержит слишком много значений.

Одним из возможных решений этой проблемы, если вы используете Hibernate 5.1 или новее, является использование Session.byMultipleIds ().

session
    .byMultipleIds(TrackedItem.class)
    .multiLoad(1L, 2L, 3L);

Для получения дополнительной информации см. https://thoughts -on-java.org / Fetch-многооконная сущность-ID-зимует /

...