我正在使用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
您可以使用setFirstResult和setMaxResults迭代较大的结果集。您可以在此related question中找到一个示例。