如何从Hibernate / JPA传输结果并释放已处理的资源?

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

我正在使用Spring Data,JPA和Hibernate在大于给定ID的每条记录上执行功能。

这是我的DAO:

public interface MyEntityDao extends JpaRepository<MyEntity, Long>, {

    @QueryHints(value = @QueryHint(name = org.hibernate.jpa.QueryHints.HINT_FETCH_SIZE, value = "1000"))
    Stream<MyEntity> findByIdGreaterThanOrderByIdAsc(Long id);
}

该方法被这样使用,并且可以起作用:

@Transactional(readOnly = true)
public void printRecordsGreaterThan(Long lastId) {
    myEntityDao.findByIdGreaterThanOrderByIdAsc(lastId).forEach((entity) -> {
        System.out.println("entity: " entity.getId());
    });
}

问题是此操作何时需要扫描很大的范围。我使用VisualVM对其进行了监视,并将所有记录保留在内存中(数十千兆字节的RAM)。

一旦处理了这些代码,有没有办法让这些代码释放资源,而不是将其保留在内存中?

提前感谢!

解决方案>>

感谢评论中的@julodnik,每隔一段时间经常在实体管理器上调用clear()解决该问题。

@PersistenceContext
private EntityManager em;

@Transactional(readOnly = true)
public void printRecordsGreaterThan(Long lastId) {
    AtomicLong counter = new AtomicLong();
    myEntityDao.findByIdGreaterThanOrderByIdAsc(lastId).forEach((entity) -> {
        long count = counter.getAndIncrement();
        if (count % 1000 == 0) {
            logger.info(String.format("Clearing %s session for result %d",  type.toString(), counter.get()));   
            em.clear();
        }
        System.out.println("entity: " entity.getId());
    });
}

我正在使用Spring Data,JPA和Hibernate对大于给定ID的每条记录执行功能。这是我的DAO:公共接口MyEntityDao扩展了JpaRepository ,{...

java postgresql hibernate spring-data-jpa
1个回答
1
投票

您可以使用setFirstResult和setMaxResults迭代较大的结果集。您可以在此related question中找到一个示例。

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