2009-03-24 16 views
6

que tienen dos entidades:Cómo filtrar la recopilación en 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; 
... 

Ahora en mi JPQL, quiero volver a esos clientes con su CustomerOrder.cost> 1000. Por ejemplo, hay tres clientes A, B y C. A tiene dos órdenes con un costo = 1000 y 2000 respectivamente. B tiene tres órdenes con un costo = 2000,3000 y 500 respectivamente. C tiene una orden con costo = 500. Ahora quiero obtener los tres clientes: A solo devuelve las órdenes con costo = 2000; B devuelve las órdenes con 2000 y 3000; C devuelve una colección de pedidos vacía.

Pero el siguiente siempre devolverá la colección completa:

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

¿Cómo se puede hacer eso en JPQL o en Hibernate en particular?

Respuesta

7

La consulta publicado es equivalente a

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

cual simplemente devuelve todos los clientes que tienen al menos un pedido con un costo superior a 1000.

que sugeriría para invertir combinación y seleccione órdenes - es semánticamente lo mismo pero estructuralmente diferente de su resultado deseado sin embargo:

select o from CustomerOrder o where o.cost > 1000 

Ahora, Hibernate tiene característica de no-APP llamado filtro que debe Acco Mplish exactamente lo que está buscando - consulte aquí: http://www.hibernate.org/hib_docs/reference/en/html/filters.html

+0

jscoot dice que devuelve todas las filas , por lo que su primera consulta puede no ser equivalente a su consulta, ya que C tiene solo un pedido, y su costo es <1000. –

0

Suena como una mala idea (en cuanto a rendimiento) tener OneToMany-relation allí.

¿Pero por qué esto no funciona: select o from CustomerOrder o where o.cost > 1000; luego de la lista de resultados extraer el del cliente?

+0

¿Por qué es una mala idea? –

0

Prueba este

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

Se puede devolver a un cliente dos veces si él tiene dos órdenes que tienen costes> 1000, para los que pueden hacer grupo por

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