code: public <T> T updateAndProcessGeneratedKeys(@NotNull ResultSetProcessor<T> generatedKeysProcessor, @NotNull List<String> columnNames, @NotNull SqlQuery query) {
          return withCurrentTransaction(query, tx -> {
              logQuery(query);
  
              try (PreparedStatement ps = prepareStatement(tx.getConnection(), query.getSql(), columnNames)) {
                  prepareStatementFromQuery(ps, query);
  
                  long startTime = currentTimeMillis();
                  ps.executeUpdate();
                  logQueryExecution(query, currentTimeMillis() - startTime);
  
                  try (ResultSet rs = ps.getGeneratedKeys()) {
                      return generatedKeysProcessor.process(rs);
                  }
              }
          });
      }
docs: Executes an update against the database and return generated keys as extracted by generatedKeysProcessor.
  
  @param generatedKeysProcessor processor for handling the generated keys
  @param columnNames names of columns that contain the generated keys. Can be empty, in which case the
  returned columns depend on the database
  @param query to execute
  @return Result of processing the results with {@code generatedKeysProcessor}.