By default, the Postgres JDBC driver loads the complete ResultSet
into memory. This can be prevented by turning off autocommit and enabling a cursor based retrieval by setting a fetch size that is greater than 0.
Details are in the manual: https://jdbc.postgresql.org/documentation/head/query.html#query-with-cursor
So if you do the following:
Connection con = ....; // open the connection
con.setAutoCommit(false);
Statement stmt = con.createStatement();
stmt.setFetchSize(1000);
ResultSet rs = stmt.executeQuery("select ...");
while (rs.next())
{
// do something with the row
}
This will never load more than 1000 rows into memory. The amount of rows held in memory can be controlled by changing the fetch size.
I don't know JPA, but the controlling autocommit should be straigh forward, but I don't know how to control the fetch size through JPA. Probably also depends on your JPA provider.