JPQL-запрос: как отфильтровать строки по отношению?
Я новичок в JPA 2.0 и несколько вещей, которые я не понимаю.
У меня есть пара таблиц:
<code> CUST table (for customers) -------------------------- CUST_ID (pk, integer) CUST_NAME (varchar) </code>
а также
<code> ORD table (for orders) ---------------------- ORD_ID (pk, integer) ORD_STATUS (char) can be: 'N' for new, 'S' for shipped, 'D' for delivered CUST_ID (fk, integer) </code>
Отношения простые "один ко многим" (каждый клиент может разместить много заказов).
Содержание таблиц:
<code> CUST_ID | CUST_NAME ------------------- 1 | elcaro 2 | tfosorcim 3 | elppa </code>
а также
<code> ORD_ID | ORD_STATUS | CUST_ID ----------------------------- 2 | N | 1 3 | N | 1 4 | N | 1 5 | S | 1 6 | S | 1 7 | D | 1 8 | D | 1 9 | D | 1 10 | D | 2 11 | N | 2 12 | S | 3 13 | S | 3 </code>
Вот как я аннотировал свои занятия:
<code> @Entity(name = "Customer") @Table(name = "CUST") public class Customer implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "CUST_ID") private Integer id; @Column(name = "CUST_NAME") private String name; @OneToMany(mappedBy = "customer") private List<Order> orders; // Default constructor, getters and setters (no annotations on these) } </code>
а также
<code> @Entity(name = "Order") @Table(name = "ORD") public class Order implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "ORD_ID") private Integer id; @Column(name = "ORD_STATUS") private Character status; @ManyToOne @JoinColumns ( { @JoinColumn(name = "CUST_ID", referencedColumnName = "CUST_ID") } ) private Customer customer; // Default constructor, getters and setters (no annotations on these) } </code>
Все работает отлично, следующий запрос JPQL дает ожидаемые результаты:
<code>`select c from Customer c`</code>
он возвращает три объекта типа Customer, каждый из которых содержит заказы, принадлежащие этому клиенту.
Но теперь я хочу извлечь список клиентов, у которых есть заказы в статусе N, вместе со связанными заказами (конечно, только статусы N заказов). Вернуться в добрый день! дни я написал бы запрос SQL, как это:
<code> select c.cust_id, c.cust_name, o.ord_id, o.ord_status from cust c inner join ord o on (o.cust_id = c.cust_id) where o.ord_status = 'N' </code>
и он возвратил бы следующий набор результатов:
<code> CUST_ID | CUST_NAME | ORD_ID | ORD_STATUS ----------------------------------------- 1 | elcaro | 2 | N 1 | elcaro | 3 | N 1 | elcaro | 4 | N 2 | tfosorcim | 11 | N </code>
Однако следующий JPQL-запрос не дает ожидаемых результатов:
<code>`select distinct c from Customer c join c.orders o where o.status = 'N'`</code>
он возвращает правильный набор клиентов (клиент 'elppa' не имеет никакого статуса 'N' и правильно исключен), но каждый клиент содержит полный набор заказов, независимо от статуса. Кажется, что "где" Предложение оценивается только для определения, какой набор клиентов должен быть извлечен, и затем поставщик постоянства начинает перемещаться по отношениям, чтобы извлечь полный набор заказов. Подумав немного об этом, я должен признать, что это имеет смысл.
Затем я попробовал другой запрос JPQL:
<code>`select c, o from Customer c join c.orders o where o.status = 'N'`</code>
этот JPQL-запрос дает результаты, аналогичные результатам, полученным в предыдущем SQL-запросе: каждый результат (4 результата, как и ожидалось) представляет собой массив из двух объектов, первый объект имеет тип Customer, а второй объект имеет тип Order. Но, опять же, объекты типа Customer содержат полный набор связанных заказов (как я и ожидал, на этот раз). Не говоря уже о том, что теперь заказы не содержатся в объектах Customer, а возвращаются отдельно, как в наборе результатов SQL.
Теперь вопрос: Можно ли написать JPQL-запрос, который отфильтровывает не только клиентов, у которых нет заказа в статусе N, но и связанных заказов (извлекаемых во время навигации по отношениям), которые не находятся в статусе N? также? То, что я хотел бы получить, это результат для 2 клиентов, где каждый клиент содержит только свой статус "N". заказы.
Я прочитал Учебное пособие по Java EE 6, и в одном из примеров (Приложение заказа) есть схема, аналогичная моей, но я не смог найти такой запрос (в загруженном исходном коде).
Хотя я думаю, что вышеупомянутое является стандартным поведением, я использую сервер Oracle Weblogic 12c (через его адаптер Eclipse), и провайдером персистентности представляется EclipseLink.
Заранее спасибо.
С наилучшими пожеланиями,
Стефано