2011-06-08 4 views
20

Я знаю, что могу передать список именованному запросу в JPA, но как насчет NamedNativeQuery? Я пробовал много способов, но все же не могу просто передать список в NamedNativeQuery. Кто-нибудь знает, как передать список в подразделение in в NamedNativeQuery? Большое спасибо!JPA, передающий список в IN-предложение в именованном собственном запросе

NamedNativeQuery, как показано ниже:

@NamedNativeQuery(
    name="User.findByUserIdList", 
    query="select u.user_id, u.dob, u.name, u.sex, u.address from user u "+ 
     "where u.user_id in (?userIdList)" 
) 

и называется так:

List<Object[]> userList = em.createNamedQuery("User.findByUserIdList").setParameter("userIdList", list).getResultList(); 

Однако результат не так как я ожидал.

System.out.println(userList.size()); //output 1 

Object[] user = userList.get(0); 
System.out.println(user.length); //expected 5 but result is 3 
System.out.println(user[0]);  //output MDAVERSION which is not a user_id 
System.out.println(user[1]);  //output 5 
System.out.println(user[2]);  //output 7 
+0

Вы пробовали выполнение точно такой же запрос с использованием своего клиента DB? –

ответ

14

Список не является допустимым параметром для собственного SQL-запроса, поскольку он не может быть связан в JDBC. У вас должен быть параметр для каждого аргумента в списке.

где u.user_id в (? Id1,? Id2)

Это поддерживается через JPQL, но не SQL, так что вы могли бы использовать JPQL вместо родного запроса.

Некоторые поставщики JPA могут поддерживать это, поэтому вы можете зарегистрировать ошибку у своего провайдера.

+3

В чем вопрос ... – SoftwareSavant

1

Пробовал в JPA2 с Hibernate как провайдером, и кажется, что спящий режим поддерживает получение списка для «IN», и он работает. (По крайней мере, для именованных запросов, и я считаю, что это будет похоже на именованные запросы NATIVE). . Что внутри спящего режима генерирует динамические параметры внутри IN так же, как количество элементов в переданном списке.

Так в вас выше примере

List<Object[]> userList = em.createNamedQuery("User.findByUserIdList").setParameter("userIdList", list).getResultList(); 

Если список содержит 2 элемента запрос будет выглядеть

select u.user_id, u.dob, u.name, u.sex, u.address from user u "+ 
     "where u.user_id in (?, ?) 

и если он имеет 3 элемента он выглядит

select u.user_id, u.dob, u.name, u.sex, u.address from user u "+ 
     "where u.user_id in (?, ?, ?) 
-1

You можете попробовать это : userIdList вместо (? UserIdList)

@NamedNativeQuery(
     name="User.findByUserIdList", 
     query="select u.user_id, u.dob, u.name, u.sex, u.address from user u "+ 
      "where u.user_id in :userIdList" 
) 
0

В зависимости от вашей базы данных/поставщик/водителя/др., Вы можете, фактически, передать список в качестве связанного параметра нативного запроса JPA.

Например, при использовании Postgres и EclipseLink следующие действия (возврат истины), демонстрация многомерных массивов и получение массива двойной точности. (Do SELECT pg_type.* FROM pg_catalog.pg_type для других типов;., Вероятно, те, с _, но лишить его перед использованием)

Array test = entityManager.unwrap(Connection.class).createArrayOf("float8", new Double[][] { { 1.0, 2.5 }, { 4.1, 5.0 } }); 
Object result = entityManager.createNativeQuery("SELECT ARRAY[[CAST(1.0 as double precision), 2.5],[4.1, 5.0]] = ?").setParameter(1, test).getSingleResult(); 

Актерский есть так буквальное массив удваивается, а не числовой.

Подробнее о проблеме - я не знаю, как или вы можете выполнять именованные запросы; Я думаю, это зависит, может быть. Но я думаю, что следующее будет работать для Array.

Array list = entityManager.unwrap(Connection.class).createArrayOf("int8", arrayOfUserIds); 
List<Object[]> userList = entityManager.createNativeQuery("select u.* from user u "+ 
    "where u.user_id = ANY(?)") 
    .setParameter(1, list) 
    .getResultList(); 

Я не имею ту же схему, как ОП, так что я не проверил это точно, но я думаю, что он должен работать - опять же, по крайней мере, на Postgres & EclipseLink.

Кроме того, ключ был найден в: http://tonaconsulting.com/postgres-and-multi-dimensions-arrays-in-jdbc/