2

次のjpa基準クエリがあります:

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Company> cq = cb.createQuery(Company.class);
    Root<Company> root = cq.from(Company.class);
    cq.select(root);

    Subquery<String> sq = cq.subquery(String.class);
    Root<Employee> subroot = sq.from(Employee.class);
    sq.select(subroot.get(Employee_.lastName));

    Predicate typePredicate = cb.equal(subroot.get(Employee_.lastName), "Doe");

    Predicate correlatePredicate = cb.equal(root.get(Company_.employees), subroot);
    sq.where(cb.and(typePredicate, correlatePredicate));
    cq.where(cb.exists(sq));


    TypedQuery<Company> typedQuery = em.createQuery(cq);
    List<Company> companies = typedQuery.getResultList();

Eclipselink は次の SQL を生成します。

    SELECT t0.ID, ... FROM COMPANY t0 
    WHERE EXISTS (SELECT t1.LASTNAME FROM EMPLOYEES t2, EMPLOYEES t1 
                  WHERE (((t1.LASTNAME = ?) AND (t1.ID = t2.ID)) 
                  AND (t2.COMPANY_ID = t0.ID))) 

ご覧のとおり、表 EMPLOYEES に不要な結合があります。この結合を取り除くにはどうすればよいですか?

4

1 に答える 1

2

クエリにサブクエリは必要ないようです。結合だけで十分です。

http://en.wikibooks.org/wiki/Java_Persistence/Criteria#Join

それ以外の場合は、どのバージョンを使用していますか? EclipseLink 2.4 を試すことができますか。

まだ重複がある場合は、バグを記録して投票してください。

OneToMany (つまり root == subroot.get("company") ) の代わりに、逆の ManyToOne を使用できる場合があります。

また、2.4 で JPQL を試してみてください。結合は最適化されていますか?

于 2012-12-04T14:46:38.070 に答える