JPQL 查询:选择一个布尔值,它是两个对象字段的 AND

发布于 2024-12-06 17:10:01 字数 1120 浏览 0 评论 0原文

假设我有一个名为 MyData 的 JPA 注解类,其中包含一个主标识符字段(名为“primaryID”的 BigDecimal 类型)和两个 Boolean 字段称为“fieldA”和“fieldB”。我想要做的是创建一个 JPA 查询,该查询将为给定的 MyData 实例选择 fieldA AND fieldB

        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:意外的 AST 节点:并靠近第 1 行...。这让我相信我需要一些不同的东西(除了 builder.isTrue 方法)来指定我想要获取对象的两个字段的布尔值和。关于如何构建这个查询有什么想法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猫卆 2024-12-13 17:10:01

好吧,我最终所做的只是将我想要“AND”的布尔值移到谓词中,然后检查是否返回了任何内容。当然,我可以简单地根据主 ID 检索整个对象 (MyData),并在 Java 代码中执行“AND”,但重点是避免获取完整对象,因为它有大量嵌套连接它引用的集合,而这些对于本例来说是不必要的。

        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;

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文