JPA с Eclipselink игнорирует левое внешнее соединение и добавляет неверное условие FROM - PullRequest
0 голосов
/ 16 апреля 2020

У меня есть объект Menu, у которого есть родительское меню:

public class Menu implements Serializable {
   ...
   @JoinColumn(name = "parent" , nullable = true, referencedColumnName = "id")
   @ManyToOne(targetEntity = Menu.class,fetch = FetchType.EAGER, cascade = {}, optional = true)
   //@BatchFetch(BatchFetchType.JOIN)
   @JoinFetch(JoinFetchType.OUTER)
   private Menu parent;
    ...
}

Я бы создал запрос:

SELECT m.*
  FROM menu m LEFT OUTER JOIN menu p ON (p.ID = m.parent)
  WHERE (m.idapp = 1) ORDER BY p.ID ASC NULLS FIRST, m.order ASC

У меня есть именованный запрос:

SELECT m FROM Menu m LEFT OUTER JOIN Menu mp 
WHERE m.applicazione.id = :idapp 
ORDER BY mp.id ASC NULLS FIRST, m.ordine ASC

но результат таков:

SELECT ... 
FROM menu t1 LEFT OUTER JOIN menu t0 ON (t0.ID = t1.parent), menu t2 
WHERE (t1.idapp = ?) ORDER BY t2.ID ASC NULLS FIRST, t1.order ASC

Это совершенно неправильно, потому что таблица t2 createa carthesian product.

В чем проблема? Почему t2 добавлено?

Я также добавил аннотацию JoinFetch, но она игнорируется, и я не знаю почему.

1 Ответ

1 голос
/ 16 апреля 2020

T1 исходит из ваших внешних объединенных отношений, и SQL показывает, что оно правильно используется для добавления всех родительских экземпляров, связанных с экземплярами меню, по которым выбирается ваш запрос.

Этот декартовой продукт с t2 - это то, что вы определили с помощью запроса «ВЫБРАТЬ m ИЗ МЕНЮ m ВЛЕВО НАРУЖНОЕ СОЕДИНЕНИЕ Меню mp» Запрос должен выглядеть следующим образом:

SELECT m FROM Menu m WHERE m.applicazione.id = :idapp ORDER BY m.ordine ASC

. Если для упорядочения необходимо использовать родительские отношения, он будет иметь вид:

SELECT m FROM Menu m LEFT OUTER JOIN m.parent mp WHERE m.applicazione.id = :idapp 
ORDER BY mp.id ASC NULLS FIRST, m.ordine ASC

. Обратите внимание, что SQL может иметь дополнительное табличное соединение, поскольку поведение определяет провайдера и спецификацию отображения c - выборочные объединения не должны использоваться при фильтрации, поскольку это может исказить результаты возвращаемых объектов.

SELECT m FROM Menu m WHERE m.applicazione.id = :idapp 
ORDER BY m.parent ASC NULLS FIRST, m.ordine ASC

может также работать в EclipseLink так как он имеет fk в Menue для работы без необходимости запуска соединения, но не обязан.

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