使用 Hibernate Criteria API 时如何获取子查询值

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

下面是一个用于检索 id 列表的子查询:

protected Long getIdList(
        @NonNull final CriteriaBuilder rootBuilder,
        @NonNull final CriteriaQuery<?> rootQuery,
        @NonNull final Pageable pageable) {
    final HibernateCriteriaBuilder listBuilder = (HibernateCriteriaBuilder) rootBuilder;
    final JpaCriteriaQuery<Long> listQuery = listBuilder.createQuery(Long.class);
    final SqmSubQuery<Tuple> subQuery = (SqmSubQuery<Tuple>) listQuery.subquery(Tuple.class);
    final SqmQuerySpec<Tuple> rootQuerySpec = ((SqmSelectStatement) rootQuery).getQuerySpec();
    final SqmQuerySpec<Tuple> subQuerySpec = rootQuerySpec.copy(SqmCopyContext.simpleContext());
    subQuery.setQueryPart(subQuerySpec);
    final Root<?> subRoot = subQuery.getRoots().iterator().next();
    subQuery.multiselect(subRoot.get("id").alias("id"));

    // listQuery.multiselect(listBuilder.count(listBuilder.literal(1))).from(subQuery);
    // instead of counting the ids, I want to get them...
    listQuery.multiselect(subRoot.get("id")).from(subQuery);

    return entityManager
        .createQuery(listQuery)
        .setFirstResult(PageableUtils.getOffsetAsInteger(pageable))
        .setMaxResults(pageable.getPageSize())
        .getResultList();
}

不幸的是它不起作用,我总是收到此错误消息:

org.springframework.orm.jpa.JpaSystemException: Could not locate TableGroup

任何提示将不胜感激。谢谢。

java spring-boot hibernate spring-data-jpa hibernate-criteria
1个回答
0
投票

我会尝试构建子查询 this 并通过提及预期类型和预期处理实体来尝试类似的事情:

import javax.persistence.criteria.*;
import javax.persistence.EntityManager;
import javax.persistence.Tuple;
import org.hibernate.query.criteria.internal.HibernateCriteriaBuilder;
import org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter;
import org.springframework.data.domain.Pageable;

public class YourRepository {

    private final EntityManager entityManager;

    public YourRepository(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    protected List<Long> getIdList(CriteriaBuilder rootBuilder, CriteriaQuery<?> rootQuery, Pageable pageable) {
        // Create the main query
        CriteriaQuery<Long> listQuery = rootBuilder.createQuery(Long.class);
        Root<?> root = rootQuery.from(YourEntity.class);

        // Create the subquery
        Subquery<Long> subQuery = listQuery.subquery(Long.class);
        Root<YourEntity> subRoot = subQuery.from(YourEntity.class);
        subQuery.select(subRoot.get("id"));

        // Add conditions to the subquery if needed
        // subQuery.where(rootBuilder.equal(subRoot.get("someField"), someValue));

        // Use the subquery in the main query
        listQuery.select(root.get("id")).where(root.get("id").in(subQuery));

        // Execute the query
        return entityManager.createQuery(listQuery)
                .setFirstResult((int) pageable.getOffset())
                .setMaxResults(pageable.getPageSize())
                .getResultList();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.