4

我正在使用 Querydsl 2.9、Spring Data JPA 1.3.0 和 Hibernate JPA 2 API 1.0 版。我正在尝试在两个表之间进行简单的连接,Parent并且ChildparentId列上连接。由于某种原因,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 byon可以得到正确的结果childId,但我不希望在cross join不必要的时候产生额外的开销。我试过两者都用innerJoinjoin但无济于事。我已经搜索了 Querydsl 文档,我可以看到默认连接类型是交叉连接,所以也许我没有正确指定我的连接?如何摆脱额外的交叉连接?

4

1 回答 1

2

来自参数的第二个可能是交叉连接的原因。

试试这个

List<Parent> parents = query.from(qParent)
    .innerJoin(qParent.children, qChild)
    .where(qParent.parentId.in(parentIds))
    .list(qParent);
于 2013-06-12T17:28:44.843 回答