Я столкнулся со странным поведением при использовании QueryDSL, интегрированного с Spring Data JPA:
У меня есть отношение ManyToOne между Project и Person. Если я получу все проекты, принадлежащие пользователю по идентификатору владельца (внешнему ключу), все будет работать, как ожидалось:
QProject project = QProject.project;
QPerson owner = project.owner;
List<Project> projects = from(project).leftJoin(owner).fetch()
.where(owner.id.eq(id)).list(project);
Сгенерированный запрос:
select
project0_.id as id1_1_0_,
person1_.id as id1_0_1_,
project0_.creation_date as creation2_1_0_,
project0_.name as name3_1_0_,
project0_.owner as owner4_1_0_,
person1_.name as name2_0_1_
from
project project0_
left outer join
person person1_
on project0_.owner=person1_.id
where
project0_.owner=?
Однако предположим, что мы хотим получить все проекты, принадлежащие человеку, по полю, которое не является внешним ключом (например, имя владельца):
QProject project = QProject.project;
QPerson owner = project.owner;
List<Project> projects = from(project).leftJoin(owner).fetch()
.where(owner.name.eq(name)).list(project);
В этих случаях таблица Person без необходимости объединяется дважды (обратите внимание на person1_ и person2_):
select
project0_.id as id1_1_0_,
person1_.id as id1_0_1_,
project0_.creation_date as creation2_1_0_,
project0_.name as name3_1_0_,
project0_.owner as owner4_1_0_,
person1_.name as name2_0_1_
from
project project0_
left outer join
person person1_
on project0_.owner=person1_.id cross
join
person person2_
where
project0_.owner=person2_.id
and person2_.name=?
Есть идеи, почему это происходит и как этого избежать?