JPQL: Внутреннее объединение без дубликатов - PullRequest
7 голосов
/ 20 ноября 2011

Ниже приведен вопрос, который предположительно был частью официального экзамена от Sun:

Сущность Reader имеет двустороннюю связь один-ко-многим с Книжная сущность. Сохраняются две сущности Читателя, каждая из которых имеет две Книги лица, связанные с ними. Например, читатель 1 имеет книгу и книга b, а у читателя 2 - книга c и книга d. Какой запрос возвращает Коллекция менее четырех элементов?
A. ВЫБЕРИТЕ b.reader ИЗ Книги b
B. ВЫБРАТЬ r ИЗ КНИГИ b ВНУТРЕННЕЕ СОЕДИНЕНИЕ b.reader r
C. ВЫБРАТЬ r ИЗ Читателя r ВНУТРЕННЕЕ СОЕДИНЕНИЕ r.books b
D. ВЫБРАТЬ r из Книги b СЛЕДУЮЩЕЕ СОЕДИНЕНИЕ

Данным ответом является C, что я считаю неверным. Насколько я понимаю, SQL с внутренним объединением двух таблиц будет сгенерирован провайдером JPA. Поэтому во всех случаях мы получим 4 записи. Я провел тест с отношением один-ко-многим, и были включены дубликаты.

Кто не прав, я или Солнце?

Ответы [ 2 ]

14 голосов
/ 03 января 2013

Ответ от Mike Keith, ведущего специализации EJB 3.0:

В спецификации есть пара утверждений, связанных с дубликатами.

  1. FETCH JOINвариант JOIN, но в нем говорится, что применяется аналогичная семантика JOIN (за исключением того, что выбрано больше данных).В спецификации (раздел 4.4.5.3 JPA v2.0) приведен пример возврата дубликатов строк Department, несмотря на тот факт, что объекты Employee отсутствуют в предложении select.

  2. Чем большеПрямая ссылка находится в разделе SELECT (раздел 4.8 JPA v2.0), где четко указывается

«Если DISTINCT не указан, дублирующиеся значения не удаляются.»

Многие поставщики JPA фактически удаляют дубликаты по нескольким причинам:

a) Удобство пользователей, поскольку некоторые пользователи недостаточно осведомлены в SQL и не ожидают их b) Обычно нетсценарий использования для запроса дуплексов c) Они могут быть добавлены в набор результатов, и если идентичность объекта сохраняется, дуплс удаляются автоматически

0 голосов
/ 21 ноября 2011

C правильно, присоединения к связям ToMany не должны возвращать дубликаты.JPA-провайдер должен автоматически использовать отчетливый для их фильтрации.Я полагаю, что это то, что требуется для спецификации, хотя это может быть одна из тех менее четко определенных областей спецификации.

Если используется выборка соединения, я считаю, что спецификация действительно требует возврата дубликатов.Что странно, можно понять, почему вы все захотите дубликаты.Если вы добавите отличное в выборку объединения, то они будут отфильтрованы (в памяти, так как все строки должны быть выбраны).

Так работает EclipseLink в любом случае.

Всев других случаях выбирают Книги, а не читателей, поэтому получайте дубликаты, C выбирает Читатели, поэтому дубликаты не должны получаться.

...