Следующее, кажется, работает для меня.Критическая часть, кажется, QueryHints.JDBC_FETCH_SIZE.Кроме того, не кеширование данных результатов очень помогает.
Query q = em.createNamedQuery("name");
q.setHint(QueryHints.CURSOR, HintValues.TRUE);
q.setHint(QueryHints.CURSOR_PAGE_SIZE, 1000);
q.setHint(QueryHints.MAINTAIN_CACHE, HintValues.FALSE);
q.setHint(QueryHints.JDBC_FETCH_SIZE, 1000);
CursoredStream cursor = (CursoredStream)q.getSingleResult();
while(cursor.hasNext()) {
MyObject o = (MyObject)cursor.next();
// do something wit data
}