You could try JPA and see if it will meet your performance needs. I am often surprised at how much data can be processed through JPA.
You may need to base your code on a specific JPA implementation to ensure it is optimized, which JPA implementation are you using?
You should ensure the query is read-only, non-transactional. If using the firstResult/maxRows does not give you the performance you are looking for you could use your JPA implementations specific query API to use a cursor (most support this, TopLink, EclipseLink, Hibernate). You could also logically partition the data by id ranges/etc.
If JPA isn't giving you good enough performance you may try raw JDBC, but this should not make a huge difference, you may need to look into raw database tools, such as your databases export functions.