我正在使用Querydsl 2.9,Spring Data JPA 1.3.0和Hibernate JPA 2 API 1.0版。我正在尝试在两个表Parent
和Child
之间进行简单连接,并加入parentId
列。出于某种原因,Hibernate执行的查询总是有一个额外的cross join
。表格如下所示:
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文档,我可以看到默认的连接类型是交叉连接,所以也许我没有正确指定我的连接?如何摆脱额外的交叉连接?
答案 0 :(得分:1)
第二个参数可能是交叉连接的原因。
试试这个
List<Parent> parents = query.from(qParent)
.innerJoin(qParent.children, qChild)
.where(qParent.parentId.in(parentIds))
.list(qParent);