I am using the Spring Data JDBC (version 1.1.6) method CrudRepository.findAllById
to load entities from a database with a large number of IDs. The underlying database connection uses a Postgres database. The invocation of the method raises a 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)
The exception seem to be ultimately caused by a 16-bit limit on the number of values in the SELECT IN (?)
clause, that is generated by Sprint Data JDBC upon using findAllById
.
Am I supposed to partition the list of IDs myself? Shouldn't the CrudRepository.findAllById
handle this correctly in a fashion compatible with the underlying database dialect?
Am I supposed to partition the list of IDs myself?
Yes, assuming this kind of query makes sense in the first place.
Spring Data JDBC currently creates a straight forward select ... where id in (..)
query which in turn is limited by the capabilities of the underlying database/JDBC driver.
With the apparent limit being ~216 for Postgres there doesn't seem to be much need for special handling in Spring Data JDBC since looking for so many ids in a single select seems rare enough to justify some manual coding.