gpt4 book ai didi

spring-boot - Spring Data JPA 分页 HHH000104

转载 作者:行者123 更新时间:2023-12-05 02:47:52 32 4
gpt4 key购买 nike

我得到了这个存储库代码:

@Query(value = "select distinct r from Reference r " +
"inner join fetch r.persons " +
"left outer join fetch r.categories " +
"left outer join fetch r.keywords " +
"left outer join fetch r.parentReferences",
countQuery = "select count(distinct r.id) from Reference r " +
"inner join r.persons " +
"left outer join r.categories " +
"left outer join r.keywords " +
"left outer join r.parentReferences")
Page<Reference> findsAllRelevantEntries(Pageable pageable);

当我对该查询运行测试时,我收到了这个 Hibernate 警告:
HHH000104:使用集合获取指定的 firstResult/maxResults;在内存中申请!

@Test
void testFindAllRelevantAsync() throws ExecutionException, InterruptedException {
CompletableFuture<Page<Reference>> all = referenceService.findAllRelevantAsync(PageRequest.of(1, 20));
CompletableFuture.allOf(all).join();
assertThat(all.get()).isNotNull();
assertThat(all.get()).isNotEmpty();
}

存储库代码封装在此处未显示的服务方法中。它(服务方法)只是编码从服务到存储库的调用并返回。

此外,生成的 sql 查询不会生成 limit 子句。尽管它确实触发了两个查询。

一个用于计数,另一个用于获取所有记录。
所以它获取所有记录并在内存中应用分页。
这会导致查询执行非常缓慢。

我怎样才能让分页与这个查询一起工作?

编辑

我知道这里经常被建议作为解决方案: How can I avoid the Warning "firstResult/maxResults specified with collection fetch; applying in memory!" when using Hibernate?

有没有办法用Spring Data JPA实现分页?我不想硬连线 EntityManager,我也不想从 BasicTransformerAdapter

扩展代码

最佳答案

您可以使用基于双查询方法的通用/可重用方法。

一个 SQL 查询用于检索实体的 ID,第二个查询使用 IN 谓词,包括来自第二个查询的 ID

实现自定义 Spring Data JPA 执行器:

@NoRepositoryBean
public interface AsimioJpaSpecificationExecutor<E, ID extends Serializable> extends JpaSpecificationExecutor<E> {

Page<ID> findEntityIds(Pageable pageable);
}


public class AsimioSimpleJpaRepository<E, ID extends Serializable> extends SimpleJpaRepository<E, ID>
implements AsimioJpaSpecificationExecutor<E, ID> {

private final EntityManager entityManager;
private final JpaEntityInformation<E, ID> entityInformation;

public AsimioSimpleJpaRepository(JpaEntityInformation<E, ID> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.entityManager = entityManager;
this.entityInformation = entityInformation;
}

@Override
public Page<ID> findEntityIds(Pageable pageable) {
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<ID> criteriaQuery = criteriaBuilder.createQuery(this.entityInformation.getIdType());
Root<E> root = criteriaQuery.from(this.getDomainClass());

// Get the entities ID only
criteriaQuery.select((Path<ID>) root.get(this.entityInformation.getIdAttribute()));

// Update Sorting
Sort sort = pageable.isPaged() ? pageable.getSort() : Sort.unsorted();
if (sort.isSorted()) {
criteriaQuery.orderBy(toOrders(sort, root, criteriaBuilder));
}

TypedQuery<ID> typedQuery = this.entityManager.createQuery(criteriaQuery);

// Update Pagination attributes
if (pageable.isPaged()) {
typedQuery.setFirstResult((int) pageable.getOffset());
typedQuery.setMaxResults(pageable.getPageSize());
}

return PageableExecutionUtils.getPage(typedQuery.getResultList(), pageable,
() -> executeCountQuery(this.getCountQuery(null, this.getDomainClass())));
}

protected static long executeCountQuery(TypedQuery<Long> query) {
Assert.notNull(query, "TypedQuery must not be null!");

List<Long> totals = query.getResultList();
long total = 0L;

for (Long element : totals) {
total += element == null ? 0 : element;
}

return total;
}
}

您可以在 https://tech.asimio.net/2021/05/19/Fixing-Hibernate-HHH000104-firstResult-maxResults-warning-using-Spring-Data-JPA.html 阅读更多内容

关于spring-boot - Spring Data JPA 分页 HHH000104,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64799564/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com