Что делает LEFT JOIN в SQL
Что проверяют
Знаете ли вы, что LEFT JOIN сохраняет строки левой таблицы, и умеете ли связать это с тем, что генерирует Hibernate. На Java-собеседовании вопрос почти всегда переходит в JPQL и в разбор запросов, которые выдаёт ORM.
Как отвечать
Определение короткое: в результат попадают все строки левой таблицы, а для тех, кому не нашлось пары справа, колонки правой таблицы заполняются NULL. INNER JOIN такие строки выбросил бы.
select e.name, d.title
from employee e
left join department d on d.id = e.department_id;Дальше переводите разговор в плоскость JPA, там ждут именно этого. В JPQL соединение идёт по полю сущности, а не по колонке:
@Query("select distinct e from Employee e left join fetch e.tasks where e.active = true")
List<Employee> findActiveWithTasks();Назовите три вещи, которые отличают знающего человека:
left join fetchтянет связанную коллекцию тем же запросом и лечит N+1, обычныйleft joinтолько участвует в условии и ничего не подгружает;- условие по правой таблице в
whereпревращает внешнее соединение во внутреннее, фильтр для правой стороны пишется вon; fetchсразу по двум коллекциям даёт декартово произведение строк, поэтому вторую берут отдельным запросом или через@BatchSize.
Где спотыкаются
Ставят условие по правой таблице в where и удивляются, что пропали строки без пары: NULL проверку не проходит, и результат совпадает с INNER JOIN. Поиск строк без пары пишется как d.id is null.
Второе: считают LEFT JOIN бесплатным способом добрать данные «на всякий случай». Лишнее соединение размножает строки левой таблицы по числу совпадений справа, и count по такому запросу завышается.
Третье: путают left join и left join fetch. Первый связь не загружает, и обращение к коллекции за пределами транзакции даёт LazyInitializationException.