2009-03-24 18 views
6

ho due entità:Come filtrare la raccolta in 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; 
... 

Ora nel mio JPQL, voglio tornare i clienti con il loro CustomerOrder.cost> 1000. Ad esempio, ci sono tre clienti A, B e C. A ha due ordini con costo = 1000 e 2000 rispettivamente. B ha tre ordini con costo = 2000,3000 e 500 rispettivamente. C ha un ordine con costo = 500. Ora voglio ottenere i tre clienti: A restituisce gli ordini solo con costo = 2000; B restituisce gli ordini con 2000 e 3000; C restituisce una raccolta ordini vuota.

ma la seguente restituirà sempre la collezione completa:

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

Come posso farlo in JPQL o in Hibernate in particolare?

risposta

7

La query postato equivale a

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

che restituisce semplicemente tutti i clienti che hanno almeno un ordine con un costo superiore a 1000.

vorrei suggerire di invertire unirsi e selezionare gli ordini - è semanticamente lo stesso, ma strutturalmente diverso dal vostro risultato desiderato però:

select o from CustomerOrder o where o.cost > 1000 

Ora, Hibernate ha caratteristica non-APP chiamato filtro che dovrebbe ACCO mplish esattamente quello che stai cercando - vedi qui: http://www.hibernate.org/hib_docs/reference/en/html/filters.html

+0

jscoot dice che restituisce tutte le righe , quindi la tua prima query potrebbe non essere equivalente alla sua query poiché C ha un solo ordine e il suo costo è <1000. –

0

Suona come una cattiva idea (in termini di prestazioni) di avere OneToMany-relazione lì.

Ma perché questo non funziona: select o from CustomerOrder o where o.cost > 1000; quindi dall'elenco dei risultati estrarre il cliente?

+0

Perché è una cattiva idea? –

0

Prova questo

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

Si può restituire un cliente due volte se ha due ordini che hanno costi> 1000, per il quale si può fare gruppo da

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