Как отфильтровать коллекцию в JPA / JPQL? - PullRequest
6 голосов
/ 24 марта 2009

У меня есть две сущности:

@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 в частности?

Ответы [ 3 ]

7 голосов
/ 24 марта 2009

Отправленный запрос эквивалентен

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 есть функция не-JPA под названием Filter, которая должна выполнять именно то, что вы ищете - смотрите здесь: http://www.hibernate.org/hib_docs/reference/en/html/filters.html

1 голос
/ 22 ноября 2012

Попробуйте это

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
0 голосов
/ 23 мая 2012

Похоже, плохая идея (с точки зрения производительности) иметь отношение OneToMany там.

Но почему это не работает: select o from CustomerOrder o where o.cost > 1000; затем из списка результатов извлекают данные Заказчика?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...