'CriteriaBuilder and or condition is not applying required/proper parenthesis
I am new this board. I tried to find solution but could not find solution. In case it is available please share me that.
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<DmdInventory> criteriaQuery = criteriaBuilder.createQuery(ItemInventory.class);
Root<ItemInventory> itemRoot = criteriaQuery.from(ItemInventory.class);
Predicate first = criteriaBuilder.equal(itemRoot.get("margin"), 1.0);
first = criteriaBuilder.and(first, criteriaBuilder.equal(itemRoot.get("costWithoutExpense"), 1.0));
first = criteriaBuilder.and(first, criteriaBuilder.equal(itemRoot.get("markup"), 1.0));
Predicate second = criteriaBuilder.and(criteriaBuilder.equal(itemRoot.get("lastImportCost"), 2.0));
second = criteriaBuilder.and(second, criteriaBuilder.equal(itemRoot.get("expenses"), 2.0));
second = criteriaBuilder.and(second, criteriaBuilder.equal(itemRoot.get("profit"), 2.0));
Predicate third = criteriaBuilder.and(criteriaBuilder.equal(itemRoot.get("totalCost"), 2.0));
third = criteriaBuilder.and(third, criteriaBuilder.equal(itemRoot.get("cost"), 2.0));
third = criteriaBuilder.and(third, criteriaBuilder.equal(itemRoot.get("quantity"), 2.0));
Predicate allPredicate[] = { first, second, third };
Predicate finalPredicate = criteriaBuilder.or(allPredicate);
criteriaQuery.where(finalPredicate);
List<ItemInventory> items = this.entityManager.createQuery(criteriaQuery).getResultList();
Current result
select * from
item_nventory inven
where
inven.last_import_cost=2.0
and inven.expenses=2.0
and inven.profit=2.0
or inven.total_cost=2.0
and inven.cost=2.0
and inven.quantity=2
or inven.margin=1.0
and inven.cost_without_expense=1.0
and inven.markup=1.0
Expected result
select * from
item_nventory inven
where
inven.last_import_cost=2.0
and inven.expenses=2.0
and inven.profit=2.0
or (inven.total_cost=2.0
and inven.cost=2.0
and inven.quantity=2 )
or (inven.margin=1.0
and inven.cost_without_expense=1.0
and inven.markup=1.0)
My final requirement will be something like below
select * from
item_nventory inven
where
inven.last_import_cost=2.0
and inven.expenses=2.0
and inven.profit=2.0
or ((inven.total_cost=2.0
and inven.cost=2.0
and inven.quantity=2 ) or (inven.quantity_on_hand>0))
or (inven.margin=1.0
and inven.cost_without_expense=1.0
and inven.markup=1.0)
Please help out me in this.
Solution 1:[1]
I think, problem is in gradual contruction of predicates. Try contruction below.
Predicate firstA = criteriaBuilder.equal(itemRoot.get("margin"), 1.0);
Predicate firstB = criteriaBuilder.equal(itemRoot.get("costWithoutExpense"), 1.0);
Predicate firstC = criteriaBuilder.equal(itemRoot.get("markup"), 1.0);
Predicate first = criteriaBuilder.and(firstA, firstB, firstC);
. . .
Predicate finalPredicate = criteriaBuilder.or(first, second, third);
Or alternative solution with list - easy to add or remove another predicates (event dynamically)
List<Predicate> allPredList = new LinkedList<>();
{
List<Predicate> firstPredList = new LinkedList<>();
firstPredList.add(criteriaBuilder.equal(itemRoot.get("margin"), 1.0));
firstPredList.add(criteriaBuilder.equal(itemRoot.get("costWithoutExpense"), 1.0));
firstPredList.add(criteriaBuilder.equal(itemRoot.get("markup"), 1.0));
allPredList.add(criteriaBuilder.and(firstPredList.toArray(new Predicate[0])));
}
. . .
Predicate finalPredicate = criteriaBuilder.or(allPredList.toArray(new Predicate[0]));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Peter Train |
