Hi i need to do a complex query, with and or condition. But the and condition seems to override the or condition here's my code:
public List<UtenteEntity> search(CartesioPojo params) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<UtenteEntity> q = cb.createQuery(UtenteEntity.class);
Root<UtenteEntity> c = q.from(UtenteEntity.class);
UtenteParams utente = (UtenteParams) params;
List<Predicate> p = new Vector<Predicate>();
if(utente.getUsername() != null && !utente.getUsername().equals(""))
p.add(cb.equal(c.get("username"), cb.literal(utente.getUsername())));
if(utente.getCognome() != null && !utente.getCognome().equals(""))
p.add(cb.and(cb.equal(c.get("cognome"), cb.literal(utente.getCognome()))));
if(utente.getRoles() != null && !utente.getRoles().isEmpty()) {
for (RuoloEntity ruolo : utente.getRoles()) {
p.add(cb.or(cb.equal(c.get("ruolo"), cb.literal(ruolo))));
}
}
q.where(p.toArray(new Predicate[p.size()]));
q.orderBy(cb.asc(c.get(USERNAME_COLUMN)));
TypedQuery<UtenteEntity> query = entityManager.createQuery(q);
List<UtenteEntity> result = query.getResultList();
return result;
}
this is the console output when I exceute this method:
executing prepstmnt 2471808 SELECT t0.SEQU_LONG_ID, t0.DATA_AGGIORNAMENTO,
t0.DATA_CREAZIONE, t0.FK_UTENTE_AGGIORNAMENTO, t0.FK_UTENTE_CREAZIONE, t0.COGNOME,
t0.FLAG_DISABILITATO, t0.NOME, t0.PASSWORD, t1.SEQU_LONG_ID, t1.DATA_AGGIORNAMENTO,
t1.DATA_CREAZIONE, t1.FK_UTENTE_AGGIORNAMENTO, t1.FK_UTENTE_CREAZIONE, t1.CODICE,
t1.DESCRIZIONE, t0.USERNAME FROM UTENTE t0, RUOLO t1 WHERE
(t0.FK_RUOLO = ? AND t0.FK_RUOLO = ?) AND t0.FK_RUOLO = t1.SEQU_LONG_ID(+)
ORDER BY t0.USERNAME ASC [params=?, ?]
To the list of predicates, you're adding, in a loop, an or clause containing a single element:
p.add(cb.or(cb.equal(c.get("ruolo"), cb.literal(ruolo))));
What you want is to create a list of predicates joined with or, and adding this long or
predicate to the main list:
List<Predicate> disjunction = new ArrayList<Predicate>();
for (RuoloEntity ruolo : utente.getRoles()) {
disjunction.add(cb.equal(c.get("ruolo"), cb.literal(ruolo)));
}
p.add(cb.or(disjunction.toArray(new Predicate[disjunction.size()])));