首页 文章

元组结果Criteria API子查询

提问于
浏览
8

我试图在我正在使用JPA 2.0类型安全标准API编写的应用程序中使用子查询,Hibernate 3.6.1.Final作为我的提供者 . 我没有选择原始类型(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
  • 这是hibernate中的一个错误,还是我做错了什么?

  • 如果你不能在子查询上使用 multiselect ,那么如何执行 groupBy

  • 如果你不能在子查询上使用 groupBy ,为什么它在API中呢?

2 回答

  • 4

    我也有同样的问题 .

    我只能尝试回答你的上一个问题,说你只能使用子查询来执行非常简单的查询,例如:

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

    我想说的另一件事是这件事让我想起了多少xkcd #979 .

  • 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();
    

    首先我选择列(在我的情况下,我只需要一列),然后我调用 where 方法与我给定的规范合并 .

相关问题