Bonjour,
J'ai un petit problème avec ma construction de requête dynamique avec l'api Criteria de JPA. En effet, j'aimerais dynamiquement construire une requête avec des OR. Mais je n'arrive pas à trouver des exemples qui me permettent de faire cela et mes tentatives jusqu'alors ont été infructueuses. Je vous poste un code générique de ce que j'ai tenté de faire pour que vous compreniez bien.
La construction dynamique des AND semble fonctionner mais celle des OR ne fonctionne pas. Je sais que cela est dû au cb.disjunction() car lorsqu'il n'y a aucune condition dans le predicate, on obtient un NullPointerException dans la classe CriteriaBuilderImpl de JPA mais je ne sais pas comment faire pour remplacer cela. J'ai essayé d'inverser le pEntier et p dans le or mais le problème persiste lorsque je met un EntiteFiltre ne contenant aucun filtre (le problème est du coup le même).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 public List<Entite> rechercheEntite(EntiteFiltre... filtresRecherche) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(); Root<Entite> entite = cq.from(entityClass); Predicate pEntier = cb.disjunction(); for (EntiteFiltre filter : filtresRecherche) { Predicate p = cb.conjunction(); if (filter != null) { if (filter.getFiltre1() != null) { p = cb.and(p, cb.equal(entite.get(Entite_.champ1), filter.getFiltre1())); } if (filter.getFiltre2() != null) { p = cb.and(p, cb.equal(entite.get(Entite_.champ2), filter.getFiltre2())); } } pEntier = cb.or(pEntier, p); } cq.select(entite).where(pEntier); return em.createQuery(cq).getResultList(); }
C'est sûr que ce n'est pas trop un problème étant donné qu'en inversant le p et le pEntier dans le or, je résoud le problème et que je n'aurais probablement jamais d'EntiteFiltre n'ayant aucun filtre mais bon sur le principe j'aimerais savoir si ce que j'ai fait est correcte et si je peux contourner le problème pour avoir une fonction sûre.
Merci d'avance pour vos réponses.
Partager