【问题标题】:How to filter collection in JPA/JPQL?如何过滤 JPA/JPQL 中的集合?
【发布时间】:2010-10-15 03:05:01
【问题描述】:

我有两个实体:

@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>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 中做到这一点?

【问题讨论】:

    标签: hibernate jpa jpql


    【解决方案1】:

    发布的查询相当于

    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

    【讨论】:

    • jscoot 说它返回所有行,所以你的第一个查询可能不等于他的查询,因为 C 只有一个订单,它的成本是
    【解决方案2】:

    试试这个

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

    如果客户有两个成本> 1000的订单,它可能会返回两次, 您可以对其进行分组

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 为什么这是个坏主意?
      猜你喜欢
      • 2017-04-12
      • 2013-03-23
      • 2021-03-16
      • 2015-05-23
      • 2020-04-20
      • 2018-06-07
      • 2018-01-10
      • 1970-01-01
      • 2016-03-08
      相关资源
      最近更新 更多