简体   繁体   中英

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". 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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM