4

Querydsl 2.9、Spring Data JPA 1.3.0、および Hibernate JPA 2 API バージョン 1.0 を使用しています。2 つのテーブル間で単純な結合を実行しようとしていますが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 joingroup byonを実行すると正しい結果が得られることはわかっていますが、必要のないときにchildId余分なオーバーヘッドが発生するのは望ましくありませんcross join。私は両方innerJoinを使用しようとしましjoinたが、役に立ちませんでした。Querydsl ドキュメントを精査したところ、デフォルトの結合タイプがクロス結合であることがわかりました。おそらく、結合を正しく指定していないのでしょうか? 余分なクロス結合を取り除くにはどうすればよいですか?

4

1 に答える 1