开发者

JPQL query: selecting a single Boolean which is the AND of two of object's fields

Suppose that I have a JPA-annotated class called MyData with a primary identifier field (BigDecimal type called "primaryID"), and two Boolean fields called "fieldA" and "fieldB". 开发者_JAVA百科What I want to do is create a JPA query that will select fieldA AND fieldB for a given MyData instance.

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

When my entityManager executes this query, I get: org.hibernate.hql.ast.QuerySyntaxException: unexpected AST node: and near line 1.... This leads me to believe that I need something different (other than the builder.isTrue method) to designate that I want to take a Boolean and of two fields of my object. Any ideas on how I should construct this query?


OK, what I ended up doing was simply moving the booleans I wanted to "AND" into the predicate instead, and just checking whether anything was returned. Of course, I could have simply retrieved the entire object (MyData) based on the primary ID, and done the "AND" in Java code, but the point was to avoid fetching the full object because it has a large number of nested joins to its referenced collections, and those would be unnecessary for this case.

        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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜