JPA CriteriaBuilder conjunction criteria into a disjunction criteria

16,698

So here it's what I did and seems that is working fine:

...  
Predicate pr1 = cb.like(article.get(Article_.code), "%" + searchQuery + "%");
Predicate pr2 = cb.like(article.get(Article_.oem_code), "%" + searchQuery + "%");
Predicate pr3 = cb.conjunction();

for (String str : busquedaSplit) {
    Predicate newPredicate = cb.like(article.get(Article_.description), "%" + str + "%");
    pr3 = cb.and(pr3, newPredicate);
}

disjunction = cb.or(pr1, pr2, pr3);

predicates.add(disjunction);
Share:
16,698
Fernando Fradegrada
Author by

Fernando Fradegrada

Updated on June 13, 2022

Comments

  • Fernando Fradegrada
    Fernando Fradegrada almost 2 years

    I need to replicate this query into JPA CriteriaBuilder code:

    ....
    where
         article.client_id = 1 
         and article.price > 0
         and (
               article.code like '%this is statement%' 
               or article.oem_code like '%this is statement%'
               or ( 
                   article.description like '%this%'
                   and article.description like '%is%'
                   and article.description like '%statement%'
               )    
         )
    

    and here's my code:

    ...
    
    Root<Article> article = cq.from(Article.class);
    
    List<Predicate> predicates = new ArrayList<Predicate>();
    
    predicates.add(cb.equal(article.get(Article_.clientId), filter.getClientId()));
    
    predicates.add(cb.greaterThan(article.get(Article_.price), BigDecimal.ZERO));
    
    String searchQuery = filter.getSearchQuery();
    
    Predicate disjunction = cb.disjunction();
    
    disjunction.getExpressions().add(cb.like(article.get(Article_.code), "%" + searchQuery + "%"));
    disjunction.getExpressions().add(cb.like(article.get(Article_.oem_code), "%" + searchQuery + "%"));
    
    List<Predicate> andPredicate = new ArrayList<Predicate>();
    
    for (String str : searchQuery.split(" ")) {
       andPredicate.add(cb.like(article.get(Article_.description), "%" + str + "%"));    
    }
    

    Now, how can I add this andPredicate to my disjunction predicate? The getExpressions().add(...) does not take a Predicate as param.

    Thanks

  • Hinotori
    Hinotori almost 7 years
    man, you helped me a lot... with this approach, we can mix AND and OR operators... how did you wrote the return statement? thanx
  • Fernando Fradegrada
    Fernando Fradegrada almost 7 years
    @Hinotori I returned it converted in an array like this predicates.toArray(new Predicate[predicates.size()]) and that is what you need to put in your cq.where('...');
  • Andrey M. Stepanov
    Andrey M. Stepanov about 5 years
    Thank you so much. Your idea to use conjunction/disjunction helped me a lot