Hibernate .getResultStream() 不流式传输?

Voj*_*ěch 2 hibernate mysql-connector

我试图通过 Hibernate 从 MySQL 流式传输大量数据.getResultStream(),但出现 OutOfMemoryErrors。

一段时间后,在第一行加载时,我会得到这个异常,我可以看到:

    at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1963) ~[mysql-connector-java-5.1.37.jar:5.1.37]
    at com.mysql.jdbc.MysqlIO.readSingleRowSet(MysqlIO.java:3308) ~[mysql-connector-java-5.1.37.jar:5.1.37]
    at com.mysql.jdbc.MysqlIO.getResultSet(MysqlIO.java:463) ~[mysql-connector-java-5.1.37.jar:5.1.37]
    at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(MysqlIO.java:3032) ~[mysql-connector-java-5.1.37.jar:5.1.37]
    at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:2280) ~[mysql-connector-java-5.1.37.jar:5.1.37]
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2673) ~[mysql-connector-java-5.1.37.jar:5.1.37]
Run Code Online (Sandbox Code Playgroud)

让我惊讶的是readAllResults——这似乎不是真正的流媒体。

我也尝试使用:

query.setHint("org.hibernate.fetchSize", 1000)
Run Code Online (Sandbox Code Playgroud)

没有效果。

然后我升级到MySQL Connector 8.0.19和Hibernate 5.4.11.Final,效果相同。

Gok*_*ner 6

有趣的是,接受的答案是错误的。正如 Mikko 所提到的,JPA 规范将实现留给了供应商,而 Hibernate 实际实现了它,请参阅QueryImpl 实现的Query类。

现在,原因在于 MySQL 的行为方式。正如这里所描述的,MySQL 默认情况下将所有结果加载到内存中。您有 2 个选项,请检查此处 -> https://vladmihalcea.com/whats-new-in-jpa-2-2-stream-the-result-of-a-query-execution/

基本上,要么将 Statement 获取大小设置为 Integer.MIN_VALUE,然后将逐个获取每条记录,或者将 useCursorFetch 连接属性设置为 true,然后您可以将 Statement 获取大小设置为正整数值(或设置 defaultFetchSize 连接)属性,因此您无需为每个查询定义)