int BATCH_SIZE = 1000;
DynamicDaoHelper dynamicDaoHelper = new DynamicDaoHelperImpl();
SessionFactory sessionFactory = dynamicDaoHelper.getSessionFactory((HibernateEntityManager) em);
Session session = sessionFactory.openSession();
Transaction tx = session.openTransaction();
// must use HQL query so that scroll.get(0) returns entity.
// if use native SQL, scroll.get() returns row object.
org.hibernate.Query q = session.createQuery(" SELECT p FROM Product p WHERE p.isProcessed = false");
ScrollableResults scroll = q.setCacheable(false).setFetchSize(100).scroll(ScrollMode.FORWARD_ONLY);
boolean hasNext = scroll.next();
try {
List<Product> batchProduct = new ArrayList<Product>(BATCH_SIZE);
while (hasNext) {
batchProduct.clear();
int count = 0;
// get a batch of products, quantity should be same as BATCH_SIZE
while (hasNext) {
Product product = (Product) scroll.get(0);
batchProduct.add(product);
count++;
hasNext = scroll.next();
if (count % BATCH_SIZE == 0 || !hasNext)
break;
}
// process batch
processBatch(batchProduct);
// persist batch and release memory
session.flush();
session.clear();
}
} finally {
scroll.close();
}
tx.commit();
session.close();
Примечания: вызов scroll.next() приведет к проверке существования и перейти к следующей записи, следует использовать логический флаг для вызова следующего() только один раз.