48 votes

Liste de passage JPA à la clause IN dans une requête native nommée

Je sais que je peux transmettre une liste à une requête nommée dans JPA, mais qu'en est-il de NamedNativeQuery ? J'ai essayé de nombreuses façons, mais je ne peux toujours pas simplement transmettre la liste à un NamedNativeQuery. Quelqu'un sait-il comment passer une liste à la clause in dans NamedNativeQuery ? Merci beaucoup!

Le NamedNativeQuery est comme ci-dessous :

 @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)"
)

et ça s'appelle comme ça :

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

Cependant le résultat n'est pas comme je l'espérais.

 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

21voto

James Points 18355

Une liste n'est pas un paramètre valide pour une requête SQL native, car elle ne peut pas être liée dans JDBC. Vous devez avoir un paramètre pour chaque argument de la liste.

où u.user_id dans (?id1, ?id2)

Ceci est pris en charge via JPQL, mais pas SQL, vous pouvez donc utiliser JPQL au lieu d'une requête native.

Certains fournisseurs JPA peuvent prendre en charge cela, vous souhaiterez donc peut-être signaler un bogue avec votre fournisseur.

6voto

Invokergb Points 48

En utilisant les données hibernate, JPA 2.1 et deltaspike, je pourrais passer une liste en tant que paramètre dans la requête qui contient la clause IN. ma requête est ci-dessous.

 @Query(value = "SELECT DISTINCT r.* FROM EVENT AS r JOIN EVENT AS t on r.COR_UUID = t.COR_UUID where " +
        "r.eventType='Creation' and t.eventType = 'Reception' and r.EVENT_UUID in ?1", isNative = true)
public List<EventT> findDeliveredCreatedEvents(List<String> eventIds);

2voto

musicccMan Points 21

actuellement j'utilise JPA 2.1 avec Hibernate

J'utilise également la condition IN avec une requête native. Exemple de ma requête

 SELECT ... WHERE table_name.id IN (?1)

J'ai remarqué qu'il est impossible de passer une chaîne comme "id_1, id_2, id_3" à cause des limitations décrites par James

Mais lorsque vous utilisez jpa 2.1 + hibernate, il est possible de passer une liste de valeurs de chaîne. Pour mon cas, le code suivant est valide :

     List<String> idList = new ArrayList<>();
    idList.add("344710");
    idList.add("574477");
    idList.add("508290");

    query.setParameter(1, idList);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X