【问题标题】:Extra Cross Join with Spring Data JPA & Querydsl使用 Spring Data JPA 和 Querydsl 进行额外的交叉连接
【发布时间】:2013-06-08 21:38:38
【问题描述】:

我正在使用 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。我意识到如果我在childId 上执行group by,我可以获得正确的结果,但我不希望cross join 在不必要的时候产生额外开销。我试过同时使用innerJoinjoin 无济于事。我已经搜索了 Querydsl 文档,我可以看到默认连接类型是交叉连接,所以也许我没有正确指定我的连接?如何摆脱额外的交叉连接?

【问题讨论】:

    标签: mysql hibernate spring-data-jpa querydsl


    【解决方案1】:

    第二个 from 参数可能负责交叉连接。

    试试这个

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-09
      • 2020-08-18
      • 2020-06-16
      • 2016-02-17
      • 2014-10-10
      • 1970-01-01
      • 2014-09-15
      相关资源
      最近更新 更多