How to exclude AND/OR predicate to be included in the condition without if else condition using criteria builder and predicates

Viewed 737

I have 2 dropdowns and 1 textbox on which i want to filter the datatable records with sprcification class in datatable api . I want or condition in the same dropdown plus AND condition between all dropdowns or textbox but if any dropdown value i am not selecting it is returning null/empty result due to AND condition . I want to exclude that dropdown to be excluded from the AND condition if it is not selected .

I have tried it with if else conditions but if i will have more dropdowns it will increase number of permutations and combinations which i do not actually want. I want something concise and performance effective. I fount solution eith criteriaQuery but i need a return type of predicate.

class FilterByMultipleObjectsForIncidentProposal<T> implements Specification<T> 
{

    private static final long serialVersionUID = 1L;
    private final IncidentReportFilters customFilter;

    public FilterByMultipleObjectsForIncidentProposal(IncidentReportFilters customFilter) {
        this.customFilter = customFilter;

    }

    @Override

    public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

        List<Predicate> businessHierarchyPredicates = new ArrayList<>();
        List<Predicate> userPredicates = new ArrayList<>();
        List<Predicate> typeOfPredicates = new ArrayList<>();
        if (this.customFilter.getBusinessHierarchy() != null) {
            for (BusinessHierarchy filterobj : this.customFilter.getBusinessHierarchy()) {
                businessHierarchyPredicates.add(criteriaBuilder.equal(root.get("incidentDept"), filterobj));
            }
        }
        if (this.customFilter.getUsers() != null) {
            for (Users filteruser : this.customFilter.getUsers()) {
                userPredicates.add(criteriaBuilder.equal(root.get("reportedBy"), filteruser));
            }
        }
        if (this.customFilter.getTypeOf() != null) {
            typeOfPredicates.add(criteriaBuilder.equal(root.get("typeof"), this.customFilter.getTypeOf()));
        }
        if (businessHierarchyPredicates.size() > 0 && userPredicates.size() > 0 && typeOfPredicates.size() > 0) {
            Predicate predicate1 = criteriaBuilder
                    .or(businessHierarchyPredicates.toArray(new Predicate[businessHierarchyPredicates.size()]));
            Predicate predicate2 = criteriaBuilder.or(userPredicates.toArray(new Predicate[userPredicates.size()]));
            Predicate predicate3 = criteriaBuilder.or(typeOfPredicates.toArray(new Predicate[typeOfPredicates.size()]));
            return criteriaBuilder.and(predicate1, predicate2, predicate3);
        } else if (businessHierarchyPredicates.size() > 0 && userPredicates.size() > 0) {
            Predicate predicate1 = criteriaBuilder
                    .or(businessHierarchyPredicates.toArray(new Predicate[businessHierarchyPredicates.size()]));
            Predicate predicate2 = criteriaBuilder.or(userPredicates.toArray(new Predicate[userPredicates.size()]));
            return criteriaBuilder.and(predicate1, predicate2);
        } else if (businessHierarchyPredicates.size() > 0 && typeOfPredicates.size() > 0) {
            Predicate predicate1 = criteriaBuilder
                    .or(businessHierarchyPredicates.toArray(new Predicate[businessHierarchyPredicates.size()]));
            Predicate predicate3 = criteriaBuilder.or(typeOfPredicates.toArray(new Predicate[typeOfPredicates.size()]));
            return criteriaBuilder.and(predicate1, predicate3);
        } else if (userPredicates.size() > 0 && typeOfPredicates.size() > 0) {
            Predicate predicate2 = criteriaBuilder.or(userPredicates.toArray(new Predicate[userPredicates.size()]));
            Predicate predicate3 = criteriaBuilder.or(typeOfPredicates.toArray(new Predicate[typeOfPredicates.size()]));
            return criteriaBuilder.and(predicate2, predicate3);
        } else if (userPredicates.size() > 0) {
            Predicate predicate2 = criteriaBuilder.or(userPredicates.toArray(new Predicate[userPredicates.size()]));
            return criteriaBuilder.and(predicate2);
        } else if (typeOfPredicates.size() > 0) {
            Predicate predicate3 = criteriaBuilder.or(typeOfPredicates.toArray(new Predicate[typeOfPredicates.size()]));
            return criteriaBuilder.and(predicate3);
        } else if (businessHierarchyPredicates.size() > 0) {
            Predicate predicate1 = criteriaBuilder
                    .or(businessHierarchyPredicates.toArray(new Predicate[businessHierarchyPredicates.size()]));
            return criteriaBuilder.and(predicate1);
        } else {
            return criteriaBuilder.conjunction();
        }

    }

}

output is right but not performance efficient. If i choose department "Fianance" and user "Adil" it should give me the record having adil as employer working in fianance dept. But if i only choose "adil" it should only return all employees having name adil but it was returning empty due to AND condition between dropdowns.Thats why i included if else conditions which i want to replace with efficient code.

0 Answers
Related