JPQL-запрос: как отфильтровать строки по отношению?
Я новичок в JPA 2.0 и несколько вещей, которые я не понимаю.
У меня есть пара таблиц:
CUST table (for customers)
--------------------------
CUST_ID (pk, integer)
CUST_NAME (varchar)
а также
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)
Отношения простые "один ко многим" (каждый клиент может разместить много заказов).
Содержание таблиц:
CUST_ID | CUST_NAME
-------------------
1 | elcaro
2 | tfosorcim
3 | elppa
а также
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
Вот как я аннотировал свои занятия:
@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)
}
а также
@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)
}
Все работает отлично, следующий запрос JPQL дает ожидаемые результаты:
`select c from Customer c`
он возвращает три объекта типа Customer, каждый из которых содержит заказы, принадлежащие этому клиенту.
Но теперь я хочу извлечь список клиентов, у которых есть заказы в статусе N, вместе со связанными заказами (конечно, только статусы N заказов). Вернуться в добрый день! дни я написал бы запрос SQL, как это:
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'
и он возвратил бы следующий набор результатов:
CUST_ID | CUST_NAME | ORD_ID | ORD_STATUS
-----------------------------------------
1 | elcaro | 2 | N
1 | elcaro | 3 | N
1 | elcaro | 4 | N
2 | tfosorcim | 11 | N
Однако следующий JPQL-запрос не дает ожидаемых результатов:
`select distinct c from Customer c join c.orders o where o.status = 'N'`
он возвращает правильный набор клиентов (клиент 'elppa' не имеет никакого статуса 'N' и правильно исключен), но каждый клиент содержит полный набор заказов, независимо от статуса. Кажется, что "где" Предложение оценивается только для определения, какой набор клиентов должен быть извлечен, и затем поставщик постоянства начинает перемещаться по отношениям, чтобы извлечь полный набор заказов. Подумав немного об этом, я должен признать, что это имеет смысл.
Затем я попробовал другой запрос JPQL:
`select c, o from Customer c join c.orders o where o.status = 'N'`
этот JPQL-запрос дает результаты, аналогичные результатам, полученным в предыдущем SQL-запросе: каждый результат (4 результата, как и ожидалось) представляет собой массив из двух объектов, первый объект имеет тип Customer, а второй объект имеет тип Order. Но, опять же, объекты типа Customer содержат полный набор связанных заказов (как я и ожидал, на этот раз). Не говоря уже о том, что теперь заказы не содержатся в объектах Customer, а возвращаются отдельно, как в наборе результатов SQL.
Теперь вопрос: Можно ли написать JPQL-запрос, который отфильтровывает не только клиентов, у которых нет заказа в статусе N, но и связанных заказов (извлекаемых во время навигации по отношениям), которые не находятся в статусе N? также? То, что я хотел бы получить, это результат для 2 клиентов, где каждый клиент содержит только свой статус "N". заказы.
Я прочитал Учебное пособие по Java EE 6, и в одном из примеров (Приложение заказа) есть схема, аналогичная моей, но я не смог найти такой запрос (в загруженном исходном коде).
Хотя я думаю, что вышеупомянутое является стандартным поведением, я использую сервер Oracle Weblogic 12c (через его адаптер Eclipse), и провайдером персистентности представляется EclipseLink.
Заранее спасибо.
С наилучшими пожеланиями,
Стефано