java 在Hibernate 6中无法使用子查询设置from子句

j2cgzkjk  于 2023-01-01  发布在  Java
关注(0)|答案(2)|浏览(160)

我有下面的代码块得到计数查询形式的原始查询.
但这是在编译时导致问题的行。countQuery.from(sqmSubQuery);

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Long> countQuery = builder.createQuery(Long.class);
SqmSubQuery sqmSubQuery = (SqmSubQuery<Tuple>) countQuery.subquery(Tuple.class);
SqmSelectStatement sqmOriginalQuery = (SqmSelectStatement) query;
SqmQuerySpec sqmOriginalQuerySpec = sqmOriginalQuery.getQuerySpec();
sqmSubQuery.setQueryPart(sqmOriginalQuerySpec.copy(SqmCopyContext.simpleContext()));

Root<T> subQuerySelectRoot = (Root<T>) sqmSubQuery.getRoots().iterator().next();
sqmSubQuery.multiselect(subQuerySelectRoot.get("id").alias("id"));

countQuery.select(builder.count(builder.literal(1)));
countQuery.from(sqmSubQuery);
ycggw6v2

ycggw6v21#

根据您的注解,您希望选择所有员工类型的非重复计数。您提供的查询应等效于SELECT COUNT(DISTINCT employee_type) FROM Employee
这可以用JPA编写,如下所示:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> countQuery = builder.createQuery(Long.class);
Root<Employee> employeeRoot = countQuery.from(Employee.class);
countQuery.select(builder.countDistinct(employeeRoot.get("type")));
Long count = entityManager.createQuery(countQuery).getSingleResult();

其中type是Map到列employee_type的属性的名称

mwyxok5s

mwyxok5s2#

类型org.hibernate.query.criteria.JpaSelectCriteria声明此方法:

<X> JpaDerivedRoot<X> from(jakarta.persistence.criteria.Subquery<X> subquery);

如果您试图在from子句中使用子查询,则需要调用该函数。
并且SqmSelectStatement实现JpaSelectCriteria(它也是实现jakarta.persistence.criteria.CriteriaQuery的对象)。
因此,可以将任意CriteriaQuery强制转换为JpaSelectCriteria,并调用from()

CriteriaQuery<Thing> query = ... ;
Subquery<OtherThing> subquery = ... ;
((JpaSelectCriteria<Thing>) query).from(subquery);

或者别的什么(我没有测试这段代码)。

相关问题