Результат кортежа Критерии API подзапрос - PullRequest
8 голосов
/ 15 марта 2011

Я пытаюсь использовать подзапросы в приложении, которое я пишу, с использованием API критериев безопасных типов JPA 2.0, с 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
  • Это ошибка в спящем режиме, или я что-то не так делаю?
  • Если вы не можете использовать multiselect в подзапросе, то как вы можете выполнить groupBy?
  • Если вы не можете использовать groupBy в подзапросе, почему он в API?

Ответы [ 2 ]

4 голосов
/ 29 ноября 2011

У меня такая же проблема.

Я могу только попытаться ответить на ваш последний вопрос, сказав, что вы действительно можете использовать только подзапросы для выполнения очень простых запросов, таких как:

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

Ещё я хотел сказать, насколько этот инцидент напоминает мне xkcd # 979 .

0 голосов
/ 04 мая 2016

У меня была похожая проблема.У меня была спецификация, и я хотел получить идентификаторы объектов, соответствующих этой спецификации.

Мое решение:

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

Сначала я выбираю столбцы (в моем случае мне нужен только один столбец), изатем я вызываю , где метод для слияния с моей заданной спецификацией.

...