如何在JPA / JPQL中过滤集合?

时间:2009-03-24 02:37:42

标签: hibernate jpa jpql

我有两个实体:

@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;
...

现在在我的JPQL中,我希望使用CustomerOrder.cost&gt; 1000来返回这些客户。例如,有三个客户A,B和C.A有两个订单,成本分别为1000和2000。 B有三个订单,成本分别为2000,3000和500。 C有一个成本= 500的订单。现在我想得到三个客户:A只返回成本= 2000的订单; B返回2000和3000的订单; C返回一个空订单集合。

但以下内容将始终返回完整集合:

select c from Customer c, in(c.customerOrders) o where o.cost>1000

我怎样才能在JPQL或Hibernate中做到这一点?

3 个答案:

答案 0 :(得分:7)

发布的查询等同于

select c from Customer c inner join c.customerOrders o where o.cost > 1000

只返回至少有一个成本大于1000的订单的所有客户。

我建议反向连接并选择顺序 - 它在语义上是相同的,但在结构上与您想要的结果不同:

select o from CustomerOrder o where o.cost > 1000

现在,Hibernate具有名为Filter的非JPA功能,可以完全满足您的需求 - 请参阅此处: http://www.hibernate.org/hib_docs/reference/en/html/filters.html

答案 1 :(得分:1)

试试这个

select c from Customer c join CustomerOrder o with o.cost > 1000

如果他有两个成本> 2的订单,它可能会返回客户两次。 1000, 您可以通过

进行分组
select c from Customer c join CustomerOrder o with o.cost > 1000
group by c

答案 2 :(得分:0)

在那里拥有OneToMany关系听起来是一个坏主意(性能方面)。

但为什么这不起作用:select o from CustomerOrder o where o.cost > 1000;然后从结果列表中提取客户的?