Entendimento de operações em lote JDBC

Eu uso o Hibernate ORM e PostgreSQL no meu aplicativo e, às vezes, uso operações em lote. E, a princípio, não entendi por que nos logs com tamanho de lote = 25, 25 consultas são geradas e, a princípio, achei que não funcionava corretamente. Mas depois disso, examinei o código-fonte do driver pg e encontrei as seguintes linhas na classe PgStatement:

 public int[] executeBatch() throws SQLException {
        this.checkClosed();
        this.closeForNextExecution();
        if (this.batchStatements != null && !this.batchStatements.isEmpty()) {
            this.transformQueriesAndParameters();
//confuses next line, because we have array of identical queries
            Query[] queries = (Query[])this.batchStatements.toArray(new Query[0]);
            ParameterList[] parameterLists = 
(ParameterList[])this.batchParameters.toArray(new ParameterList[0]); 
            this.batchStatements.clear();
            this.batchParameters.clear();

e na classe PgPreparedStatement

    public void addBatch() throws SQLException {
        checkClosed();
        if (batchStatements == null) {
          batchStatements = new ArrayList<Query>();
          batchParameters = new ArrayList<ParameterList>();
        }

        batchParameters.add(preparedParameters.copy());
        Query query = preparedQuery.query;
    //confuses next line
        if (!(query instanceof BatchedQuery) || batchStatements.isEmpty()) {
          batchStatements.add(query);
        }
      }

Percebi que, se o tamanho do lote ultrapassar 25, são enviadas 25 consultas com os parâmetros anexados.

Os logs do banco de dados confirmam isso, por exemplo:

2017-12-06 01:22:08.023 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ:  выполнение S_3: BEGIN
2017-12-06 01:22:08.024 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ:  выполнение S_4: select nextval ('tests_id_seq')
2017-12-06 01:22:08.041 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ:  выполнение S_2: insert into tests (name, id) values ($1, $2)     
2017-12-06 01:22:08.041 MSK [18402] postgres@buzzfactory ПОДРОБНОСТИ:  параметры: $1 = 'test', $2 = '1'
2017-12-06 01:22:08.041 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ:  выполнение S_2: insert into tests (name, id) values ($1, $2)
2017-12-06 01:22:08.041 MSK [18402] postgres@buzzfactory ПОДРОБНОСТИ:  параметры: $1 = 'test', $2 = '2'
...
x23 queries with parameters 
...
2017-12-06 01:22:08.063 MSK [18402] postgres@buzzfactory СООБЩЕНИЕ:  выполнение S_5: COMMIT

Mas eu pensei que uma consulta deve ser executada com uma matriz de 25 parâmetros. Ou não entendo como as inserções em lote funcionam com uma instrução preparada? Por que duplicar uma consulta n vezes?

Afinal, tentei depurar minhas consultas neste local

if (!(query instanceof BatchedQuery) || batchStatements.isEmpty()) {

e notei que minhas consultas são sempre uma instância do SimpleQuery em vez de BatchedQuery. Talvez esta seja a solução para o problema? Informações sobre o BatchedQuery que não consegui encontrar

questionAnswers(2)

yourAnswerToTheQuestion