使用Spring Data JPA& amp; Querydsl

时间:2013-06-12 17:01:30

标签: mysql hibernate spring-data-jpa querydsl

我正在使用Querydsl 2.9,Spring Data JPA 1.3.0和Hibernate JPA 2 API 1.0版。我正在尝试在两个表ParentChild之间进行简单连接,并加入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 bychildId,我可以得到正确的结果,但我不希望cross join在没有必要的情况下额外开销。我尝试过使用innerJoinjoin都无济于事。我已经搜索了Querydsl文档,我可以看到默认的连接类型是交叉连接,所以也许我没有正确指定我的连接?如何摆脱额外的交叉连接?

1 个答案:

答案 0 :(得分:1)

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

试试这个

List<Parent> parents = query.from(qParent)
    .innerJoin(qParent.children, qChild)
    .where(qParent.parentId.in(parentIds))
    .list(qParent);