Hibernate / JPA: как заставить неявные объединения использовать LEFT OUTER JOINS - PullRequest
14 голосов
/ 25 января 2012

Существует класс Offer, который имеет необязательное отношение к классу Article.Так что в некоторых предложениях свойство article содержит значение null.

Если я использую следующее утверждение, все работает нормально.Я получил все предложения, даже те, у которых нет статьи.

SELECT o FROM Offer o 
         LEFT OUTER JOIN o.article a 
         LEFT OUTER JOIN o.vendor v 
         WHERE v.number = '0212' OR a.nummer = '123456'

Если я изменил утверждение на:

SELECT o FROM Offer o 
         LEFT OUTER JOIN o.article a 
         LEFT OUTER JOIN o.vendor v 
         WHERE v.number = '0212' OR o.article.nummer = '123456'

, я получил только эти предложения, в которых статьи отличались от NULL.Это связано с тем, что нотация для неявных объединений (o.article.nummer) вызывает внутреннее объединение.

Существует ли возможность принудительного включения левых внешних объединений в неявные объединения (управляемые аннотациями или что-то еще)?Если есть возможность, я мог бы использовать короткую форму, например, такую:

SELECT o FROM Offer o 
         WHERE v.number = '0212' OR o.article.nummer = '123456'

Ответы [ 4 ]

4 голосов
/ 06 марта 2012

Вы можете попробовать указать @Fetch(FetchMode.JOIN) в свойстве Article. Однако это аннотация Hibernate.

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

//...

@ManyToOne
@Fetch(FetchMode.JOIN)
Article article;
1 голос
/ 13 апреля 2016

У меня была похожая проблема: у меня была какая-то таблица GeneralFacility, содержащая столбец SpecificType.Не у всех объектов был этот тип, и поскольку SpecificType был внутренне объединен в записях таблицы GeneralFacility без указания конкретного типа, попал под таблицу.

Я решил проблему, поставив

    @Fetch(FetchMode.SELECT)

далеедо @ManyToOne -линии в модели.Тип теперь выбирается в отдельном запросе, и если он ничего не возвращает, результаты запроса GeneralFacility НЕ отбрасываются.

1 голос
/ 26 марта 2014

Насколько я мог понять, Hibernate не предлагает способ изменить неявную форму объединения по умолчанию для объединения запросов HQL.

лучшие решения Я мог бы найти для себя:

  • Построить запрос с явной информацией о соединении;
  • Использовать критерии, которые, вероятно, лучше всего подходят для динамического построения запроса.
0 голосов
/ 26 октября 2014

Прежде всего, если вы попытаетесь использовать o.article.nummer вместо a.nummer, я полагаю, что это добавит дополнительное предложение WHERE с внутренним объединением. Нет никакого способа явно сказать, левые соединения. Но вы все равно сами указываете его в запросе, поэтому просто используйте объединенную сущность из псевдонима a.number = '23456'.

Так как вы знаете, что поле можно обнулять, вы не можете использовать = так же, как вы не можете использовать = в SQL для полей, допускающих обнуляемость. Вместо этого используйте COALESCE для преобразования значений NULL в пустую строку для этой цели:

SELECT o FROM Offer o 
    LEFT OUTER JOIN o.article a
    LEFT OUTER JOIN o.vendor v 
        WHERE v.number = '0212'
        OR COALESCE(a.nummer,'') = '123456'
...