title: JPA Criteria builder How to group logical AND conditions
body: <p>JPA Criteria builder How to group logical operator AND</p>
  
  <p>Current</p>
  
  <p>select * from Offers marketingo0_ where (upper(marketingo0_.SOURCE_KEY_UID)=? OR marketingo0_.STATUS=? and marketingo0_.STATUS=? ) </p>
  
  <p>Expected</p>
  
  <p>select * from Offers marketingo0_ where upper(marketingo0_.SOURCE_KEY_UID)=? OR (marketingo0_.STATUS=? and marketingo0_.STATUS=? ) </p>
  
  <pre><code>        List&lt;Predicate&gt; innerPredicates = new ArrayList&lt;Predicate&gt;();
      List&lt;Predicate&gt; predicates = new ArrayList&lt;Predicate&gt;();
      List&lt;Predicate&gt; outerPredicates = new ArrayList&lt;Predicate&gt;();
  
  
      //Create all outer predicates
      createPredicates(filter.getRootBooleanClause(),builder, marketingOffer, outerPredicates);
  
  
      //Create all sub clauses predicates
      for (BooleanClause subClause : filter.getRootBooleanClause().getSubClauses()) {
  
          List&lt;Predicate&gt; groupPredicates = new ArrayList&lt;Predicate&gt;();
  
          createPredicates(subClause,builder, marketingOffer, groupPredicates);
  
          if(groupPredicates!=null &amp;&amp; groupPredicates.size()&gt;0 &amp;&amp; filter.getOperator().equals(LogicOperator.OR)){
              innerPredicates.add(builder.and(groupPredicates.toArray(new Predicate[groupPredicates.size()])));
          }else if(groupPredicates!=null &amp;&amp;  groupPredicates.size()&gt;0 &amp;&amp; filter.getRootBooleanClause().getOperator().equals(LogicOperator.AND)){
              innerPredicates.add(builder.or(groupPredicates.toArray(new Predicate[groupPredicates.size()])));
          }
      }
  
      if(innerPredicates.size()&gt;0){
          outerPredicates.addAll(innerPredicates);
      }
  
  
      if(outerPredicates.size()&gt;0 &amp;&amp; filter.getRootBooleanClause().getOperator().equals(LogicOperator.OR)){
          predicates.add(builder.or(outerPredicates.toArray(new Predicate[outerPredicates.size()])));
      }else if(outerPredicates.size()&gt;0 &amp;&amp; filter.getRootBooleanClause().getOperator().equals(LogicOperator.AND)){
          predicates.add(builder.and(outerPredicates.toArray(new Predicate[outerPredicates.size()])));
      }
  </code></pre>