8

Hibernate 3.6.1.Finalをプロバイダーとして、JPA2.0タイプセーフ基準APIを使用して作成しているアプリケーションでサブクエリを使用しようとしています。プリミティブ型(Long、MyEntityなど)を選択するのに問題はありませんが、複数の列を選択したいと思います。

これは完全に合理的なものの例です。サブクエリの不必要な使用は無視してください。これは単に説明のためのものです。

    EntityManager em = getEntityManager();
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Tuple> cq = cb.createTupleQuery();

    Subquery<Tuple> subQ = cq.subquery(Tuple.class);
    Expression<Long> subqCount;
    {
        Root<MyEntity> root = subQ.from(MyEntity.class);
        Path<MyEntity> filter = root.get(MyEntity.challenge);

        subqCount = cb.count(root);

        // How to select tuple?
        Selection<Tuple> tuple = cb.tuple(filter, subqCount);

                    // !! Run-time exception here
        Expression<Tuple> tupleExpr = (Expression<Tuple>) tuple; 

        // Not sure why I can't use multiSelect on a subQuery
        // #select only accepts Expression<Tuple>
        createSubQ.select(tupleExpr);

        createSubQ.groupBy(filter);
    }

    cq.multiselect(subqCount);

コンパイラは文句を言いませんが、それでも実行時例外が発生します。

    java.lang.ClassCastException: org.hibernate.ejb.criteria.expression.CompoundSelectionImpl cannot be cast to javax.persistence.criteria.Expression
  • これは休止状態のバグですか、それとも私は何か間違ったことをしていますか?
  • multiselectサブクエリで使用できない場合、どのように実行できますgroupByか?
  • サブクエリで使用できない場合groupBy、なぜそれがAPIにあるのですか?
4

2 に答える 2

5

私も同じ問題を抱えてる。

私はあなたが本当にサブクエリを使用して次のような非常に単純なクエリを実行することしかできないと言うことによってあなたの最後の質問に答えることを試みることができるだけです:

SELECT name FROM Pets WHERE Pets.ownerID in (
    SELECT ID FROM owners WHERE owners.Country = "SOUTH AFRICA"
)

もう1つ言いたかったのは、この事件がxkcd#979をどれだけ思い出させるかということでした。

于 2011-11-29T09:07:19.700 に答える
0

私も同様の問題を抱えていました。仕様があり、この仕様に一致するオブジェクトのIDを取得したかったのです。

私の解決策:

    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Tuple> tupleCriteriaQuery = criteriaBuilder.createTupleQuery();

    Root<Issue> root = tupleCriteriaQuery.from(Issue.class);
    tupleCriteriaQuery = tupleCriteriaQuery.multiselect(root.get(IssueTable.COLUMN_ID));//select did not work.
    tupleCriteriaQuery = tupleCriteriaQuery.where(issueFilter.toPredicate(root, tupleCriteriaQuery, criteriaBuilder));

    List<Tuple> tupleResult = em.createQuery(tupleCriteriaQuery).getResultList();

最初に列を選択し(私の場合は1つの列のみが必要です)、次にwhereメソッドを呼び出して指定された仕様とマージします。

于 2016-05-04T09:17:53.037 に答える