I have two entities:
@Entity
public class Customer implements java.io.Serializable {
...
@OneToMany(fetch=FetchType.EAGER, mappedBy="customer")
private Set<CustomerOrder> customerOrders;
...
@Entity
public class CustomerOrder implements java.io.Serializable {
....
private double cost;
@ManyToOne
@JoinColumn(name="CUST_ID")
public Customer customer;
...
Now in my JPQL, I want to return those customers with their CustomerOrder.cost>1000. For example, there are three customers A, B and C. A has two orders with cost=1000 and 2000 respectively. B has three orders with cost=2000,3000 and 500 respectively. C has one order with cost=500. Now i want to get the three customers: A returns the orders with cost=2000 only; B returns the orders with 2000 and 3000; C returns an empty orders collection.
But the following will always return the full collection:
select c from Customer c, in(c.customerOrders) o where o.cost>1000
How can I do that in JPQL or in Hibernate in particular?
JPQL WHERE Clause. The WHERE clause of a query consists of a conditional expression used to select objects or values that satisfy the expression. The WHERE clause restricts the result of a select statement or the scope of an update or delete operation.
JPQL provides an additional type of identification variable, a join variable, which represent a more limited iteration over specified collections of objects. In JPQL, JOIN can only appear in a FROM clause. The INNER keyword is optional (i.e. INNER JOIN is equivalent to JOIN).
The WHERE clause is used to apply conditions on database and fetch the data on the basis of that condition. In Criteria API, the where() method of AbstractQuery interface is used to set conditions.
The WHERE clause adds filtering capabilities to the FROM-SELECT structure. It is essential in any JPQL query that retrieves selective objects from the database. Out of the four optional clauses of JPQL queries, the WHERE clause is definitely the most frequently used.
The query posted is equivalent to
select c from Customer c inner join c.customerOrders o where o.cost > 1000
which simply returns all customers that have at least one order with cost greater than 1000.
I would suggest to inverse join and select orders - it's semantically the same but structurally different from your desired result though:
select o from CustomerOrder o where o.cost > 1000
Now, Hibernate has non-JPA feature called Filter that should accomplish exactly what you are looking for - see here: http://www.hibernate.org/hib_docs/reference/en/html/filters.html
Try this
select c from Customer c join CustomerOrder o with o.cost > 1000
It may return a customer twice if he has two orders having cost > 1000, for which you can do group by
select c from Customer c join CustomerOrder o with o.cost > 1000
group by c
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With