Reputation: 1475
I have a List to append in an or condition
The Issue I am facing is when I am iterating over the List and adding it to the CategoryBuilder then it takes the last Predicate
Following is the example:
public static Specification<Billoflading> hasTenantAndBillingCodeCombination(List<WhoOwnsIt> list,
Date formattedFromDate, Date formattedToDate, String carrierFilter, String supplierFilter,
String terminalFilter) {
return (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
for (WhoOwnsIt whoOwnsIt : list) {
String containsLikePatternForTenant = getContainsLikePattern(whoOwnsIt.getWholesalerTenantID(), true);
Predicate pred = cb.and(cb.like(cb.lower(root.<String>get("tenant")), containsLikePatternForTenant),
cb.equal(cb.lower(root.<String>get("billingCode")), whoOwnsIt.getBillingCode()),
cb.greaterThanOrEqualTo(root.<Date>get("scheduleDate"), formattedFromDate),
cb.lessThanOrEqualTo(root.<Date>get("scheduleDate"), formattedToDate));
Predicate predWithTenant = null;
if (null != carrierFilter) {
predWithTenant = cb.and(cb.equal(cb.lower(root.<String>get("tenant")), carrierFilter));
}
if (null != predWithTenant)
predicates.add(predWithTenant);
else
predicates.add(pred);
}
Predicate finalPredicate;
// This commented section below needs to be replaced with a
//better solution
//for(Predicate predicate : predicates){
// cb.or(predicate);
//}
return finalPredicate;
};
}
I also tried making the List an array for passing it to the finalPredicate.or as follows
Predicate finalQuery = cb.or(predicates.toArray());
But this code gave compilation error as the parameters needed is varargs i.e.
or method accepts (Predicate... predicates) as parameter list
Can you please provide some simple solution to this issue?
Upvotes: 11
Views: 42382
Reputation: 364
A sample code I wrote that might be helpful. Here, I gather all predicates in a list and then convert the list to an array which is getting consumed by a builder.
public List< EntityClass> getData(List<Long> ids) {
List<List<Long>> idPartitions = ListUtils.partition(ids, 999);
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<EntityClass> criteria = builder.createQuery(EntityClass.class);
Root<EntityClass> root = criteria.from(EntityClass.class);
List<Predicate> predicates = new ArrayList<>(idPartitions.size());
for (List<Long> idPartition : idPartitions) {
predicates.add(root.get("id").in(idPartition));
}
criteria.where(builder.and(predicates.toArray(new Predicate[0])));
List<EntityClass> objects = entityManager.createQuery(criteria).getResultList();
return objects;
}
Upvotes: 2
Reputation: 91
As an addition I would suggest using the following notation for newer Java versions:
builder.or(predicates.toArray(Predicate[]::new))
Upvotes: 8
Reputation: 2616
Try this:
Predicate finalQuery = cb.or(predicates.toArray(new Predicate[0]));
Upvotes: 34