Я использую Querydsl 2.9, Spring Data JPA 1.3.0 и Hibernate JPA 2 API версии 1.0. Я пытаюсь сделать простое соединение между двумя таблицами: Parent
и Child
, присоединившись к столбцу parentId
. По какой-то причине запрос, который выполняется Hibernate, всегда содержит дополнительный cross join
. Таблицы выглядеть следующим образом:Extra Cross Присоединиться к данным Spring JPA & Querydsl
CREATE TABLE PARENT (
PARENTID INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(255)
);
CREATE TABLE CHILD (
CHILDID INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
PARENTID INT(11),
NAME VARCHAR(255)
);
Классы домена выглядеть следующим образом:
@Entity
@Table(name="PARENT")
public class Parent {
@Id
@GeneratedValue
private Integer parentId;
private String name;
@OneToMany
@JoinColumn(name="parentId")
private List<Child> children;
// ... getters/setters omitted for brevity
}
@Entity
@Table(name="CHILD")
public class Child {
@Id
@GeneratedValue
private Integer childId;
private Integer parentId;
private String name;
// ... getters/setters omitted for brevity
}
Мой код запроса выглядит следующим образом:
private List<Parent> test(List<Integer> parentIds) {
JPAQuery query = new JPAQuery(entityManagerFactory.createEntityManager());
QParent qParent = QParent.parent;
QChild qChild = QChild.child;
List<Parent> parents = query.from(qParent, qChild)
.innerJoin(qParent.children, qChild)
.where(qParent.parentId.in(parentIds))
.list(qParent);
return parents;
}
Я ожидал бы сгенерированный запрос выглядеть например:
select
p.parentId, p.name
from
parent p
inner join
child c on c.parentid = p.parentid
where
p.parentid in(1, 2);
Однако запрос, который на самом деле запустить это:
select
parent0_.parentId as parentId1_3_, parent0_.name as name2_3_
from
PARENT parent0_
inner join
CHILD children2_ ON parent0_.parentId = children2_.parentId
cross join
CHILD child1_
where
parent0_.parentId in (1 , 2);
Обратите внимание на дополнительные cross join
в конце. Я понимаю, что могу получить правильные результаты, если я сделаю group by
по адресу childId
, но я не хочу лишних накладных расходов cross join
, когда это не обязательно. Я пробовал использовать как innerJoin
, так и join
безрезультатно. Я просмотрел документы Querydsl, и я вижу, что тип соединения по умолчанию - это перекрестное соединение, поэтому, возможно, я не правильно определяю свое соединение? Как я могу избавиться от дополнительного кросс-соединения?