The solution is to stream the results and scroll through them using the Query.scroll() method. For best results, the following also should be done:
- Scroll with ScrollMode.FORWARD_ONLY
- Use a StatelessSession (to avoid caching)
- Set fetch size to Integer.MIN_VALUE (this one I'm not 100% sure about, but it's recommended in some blogs)
References: