对两个条件查询使用相同的谓词

问题描述 投票:0回答:1

我想使用相同的Predicate数组运行一对查询:一个要对记录进行计数,一个要获取记录的特定页面。对我来说,这似乎是一个非常正常的用例,因此必须有一种很好的方法来完成它,但我还没有找到它。

所以这是获取实体的部分:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
EntityType<ENTITY> entityType = entityManager.getMetamodel().entity(FooEntity.class);
CriteriaQuery<FooEntity> entityQuery = criteriaBuilder.createQuery(FooEntity.class);
Root<FooEntity> entityRoot = entityQuery.from(FooEntity.class);

// Use the criteria builder, root, and type to create some predicates.
Predicate[] predicates = createPredicates(criteriaBuilder, entityRoot, entityType );

// Fetch the entities.
entityQuery.select(entityRoot);
entityQuery.where(predicates);
List<FooEntity> entities = entityManager.createQuery(entityQuery)
    .setFirstResult(0) // Just get the first page
    .setMaxResults(50)
    .getResultList();

这有效。我们得到了我们想要的东西,谓词是正确的,等等。

但是,使用相同的谓词创建另一个查询来确定计数失败。我尝试了两种不同的方法:

((1)重用Root

CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
countQuery.select(criteriaBuilder.count(entityRoot));
countQuery.where(predicates);
long count = entityManager.createQuery(countQuery).getSingleResult();

这不起作用,并给了我java.lang.IllegalStateException: No criteria query roots were specified。奇怪,因为我清楚地指定了Root,但是也许我不能重用从另一个Root创建的CriteriaQuery?好的,让我们从相同的CriteriaQuery ...]中创建一个

((2)创建新的Root

CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
countQuery.select(criteriaBuilder.count(countQuery.from(FooEntity.class));
countQuery.where(predicates);
long count = entityManager.createQuery(countQuery).getSingleResult();

现在我们得到了另一个错误:org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'generatedAlias1.fooProperty' [select count(generatedAlias0) from com.foo.FooEntity as generatedAlias0 where ( generatedAlias1.fooProperty = :param0 )]

[查看所创建的HQL,似乎“ from”子句设置了generatedAlias0,但是“ where”子句中的所有内容都引用了generatedAlias1。我的猜测是因为Predicate的数组是使用与Root中使用的不同的CriteriaQuery<Long>构建的。

因此,如果这两种方法都不起作用,我将如何重新使用同一数组Predicate?我真的必须使用第二个Root重新创建所有这些文件吗?对我来说,这似乎太过分了,尤其是因为它们都是Root<FooEntity>。我觉得必须有更好的方法。

我想使用相同的谓词数组运行一对查询:一个要对记录进行计数,一个要获取记录的特定页面。对我来说,这似乎是一个非常正常的用例,因此必须有一个...

java hibernate jpa criteria-api
1个回答
0
投票

如果使用Spring

© www.soinside.com 2019 - 2024. All rights reserved.