2009-03-24 24 views
6

Tôi có hai thực thể:Làm cách nào để lọc bộ sưu tập trong 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; 
... 

Bây giờ trong JPQL của tôi, tôi muốn quay trở lại những khách hàng với CustomerOrder.cost họ> 1000. Ví dụ, có ba khách hàng A, B và C. A có hai đơn đặt hàng với chi phí = 1000 và 2000 tương ứng. B có ba đơn đặt hàng với chi phí = 2000,3000 và 500 tương ứng. C có một đơn đặt hàng với chi phí = 500. Bây giờ tôi muốn có được ba khách hàng: A trả lại các đơn đặt hàng với chi phí = 2000 chỉ; B trả về các lệnh với 2000 và 3000; C trả về một bộ sưu tập đơn đặt hàng trống.

Nhưng sau đây sẽ luôn luôn trở lại đầy đủ bộ sưu tập:

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

Làm thế nào tôi có thể làm điều đó trong JPQL hoặc Hibernate đặc biệt?

Trả lời

7

Truy vấn đăng là tương đương với

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

mà chỉ đơn giản trả về tất cả các khách hàng rằng có ít nhất một đơn đặt hàng với chi phí lớn hơn 1000.

tôi sẽ đề nghị để đảo tham gia và chọn lệnh - đó là ngữ nghĩa giống nhau nhưng có cấu trúc khác với kết quả mong muốn của bạn mặc dù:

select o from CustomerOrder o where o.cost > 1000 

Bây giờ, Hibernate có tính năng không phải JPA được gọi là Bộ lọc nên acco mplish chính xác những gì bạn đang tìm kiếm - xem tại đây: http://www.hibernate.org/hib_docs/reference/en/html/filters.html

+0

jscoot nói nó sẽ trả về tất cả các hàng , vì vậy truy vấn đầu tiên của bạn có thể không tương đương với truy vấn của anh vì C chỉ có một đơn đặt hàng và chi phí của nó là <1000. –

0

Âm thanh như một ý tưởng tồi (hiệu suất khôn ngoan) để có mối quan hệ OneToMany ở đó.

Nhưng tại sao điều này không hoạt động: select o from CustomerOrder o where o.cost > 1000; sau đó từ danh sách kết quả trích xuất của Khách hàng?

+0

Tại sao lại là một ý tưởng tồi? –

0

Hãy thử điều này

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

Nó có thể trả về một khách hàng hai lần nếu ông có hai đơn đặt hàng có giá> 1000, mà bạn có thể làm nhóm bởi

select c from Customer c join CustomerOrder o with o.cost > 1000 
group by c 
Các vấn đề liên quan