Spring 数据 CrudRepository.findAllById 大量 ID 异常

Spring Data CrudRepository.findAllById exception with large number of IDs

我正在使用 Spring 数据 JDBC(版本 1.1.6)方法 CrudRepository.findAllById 从具有大量 ID 的数据库中加载实体。底层数据库连接使用 Postgres 数据库。该方法的调用引发 PSQLException:

2020-05-28 05:58:35,260 WARN com.zaxxer.hikari.pool.ProxyConnection [task-2] HikariPool-1 - Connection org.postgresql.jdbc.PgConnection@1224f39f marked as broken because of SQLSTATE(08006), ErrorCode(0)
org.postgresql.util.PSQLException: An I/O error occurred while sending to the backend.
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:358)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:448)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:369)
    at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:159)
    at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:109)
...
Caused by: java.io.IOException: Tried to send an out-of-range integer as a 2-byte value: 137525
    at org.postgresql.core.PGStream.sendInteger2(PGStream.java:275)
    at org.postgresql.core.v3.QueryExecutorImpl.sendParse(QueryExecutorImpl.java:1553)
    at org.postgresql.core.v3.QueryExecutorImpl.sendOneQuery(QueryExecutorImpl.java:1876)
    at org.postgresql.core.v3.QueryExecutorImpl.sendQuery(QueryExecutorImpl.java:1439)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:323)

异常似乎最终是由 SELECT IN (?) 子句中的值数量的 16 位限制引起的,这是由 Sprint Data JDBC 在使用 findAllById 时生成的.

我应该自己对 ID 列表进行分区吗? CrudRepository.findAllById 不应该以与底层数据库方言兼容的方式正确处理这个问题吗?

Am I supposed to partition the list of IDs myself?

是的,首先假设这种查询是有意义的。

Spring 数据 JDBC 当前创建一个直接的 select ... where id in (..) 查询,而该查询又受到基础 database/JDBC 驱动程序功能的限制。

由于 Postgres 的明显限制是 ~216,因此似乎不需要对 Spring 数据 JDBC 进行特殊处理,因为在一个 select 中寻找如此多的 ID 似乎很少见,足以证明一些手动编码是合理的。