JPQL-запрос: выбор одного логического значения, являющегося AND двух полей объекта - PullRequest
0 голосов
/ 26 сентября 2011

Предположим, у меня есть JPA-аннотированный класс с именем MyData с полем первичного идентификатора (тип BigDecimal с именем "primaryID") и двумя полями Boolean с именами "fieldA" и "fieldB".Я хочу создать JPA-запрос, который выберет fieldA AND fieldB для данного MyData экземпляра.

        final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        final CriteriaQuery<Boolean> boolQuery = builder.createQuery(Boolean.class);
        final Root<MyData> data = boolQuery.from(MyData.class);
        boolQuery.select(builder.isTrue(builder.and(data.<Boolean> get("fieldA"),
                profile.<Boolean> get("fieldB"))));
        final Predicate primaryIDPredicate = builder.equal(profile.<BigDecimal> get("primaryID"),
                1000);
        boolQuery.where(primaryIDPredicate);

        final TypedQuery<Boolean> myQuery = entityManager.createQuery(boolQuery);

Когда мой entityManager выполняет этот запрос, я получаю: org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node: and near line 1....Это заставляет меня поверить, что мне нужно что-то другое (кроме метода builder.isTrue), чтобы обозначить, что я хочу взять логическое значение и два поля моего объекта.Любые идеи о том, как я должен построить этот запрос?

1 Ответ

0 голосов
/ 29 сентября 2011

ОК, в итоге я просто переместил логические значения, которые я хотел вместо «И» в предикат, и просто проверил, было ли что-нибудь возвращено. Конечно, я мог бы просто получить весь объект (MyData) на основе первичного идентификатора и выполнить «И» в коде Java, но смысл состоял в том, чтобы избежать выборки полного объекта, поскольку он имеет большое количество вложенных объединений в его ссылочные коллекции, и в этом случае они не нужны.

        final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
        final CriteriaQuery<BigInteger> primaryIDQuery = builder.createQuery(BigInteger.class);
        final Root<MyData> data = primaryIDQuery.from(MyData.class);
        primaryIDQuery.select(data.<BigInteger> get("primaryId"));
        final Predicate primaryIDPredicate = builder.equal(profile.<BigInteger> get("primaryId"),1000);
        final Predicate otherPredicate = builder.or(
                builder.isTrue(profile.<Boolean> get("fieldA")),
                builder.isTrue(profile.<Boolean> get("fieldB")));
        primaryIDQuery.where(primaryIDPredicate , otherPredicate);

        final TypedQuery<BigInteger> existenceQuery = entityManager.createQuery(primaryIDQuery);

        boolean whatIWant = existenceQuery.getResultList().size() > 0;
...