Bug #71528 batch inserts with rewriteBatchedStatements=true returns incorrect row counts
Description:
If you execute batched inserts with rewriteBatchedStatements=true set on the connection, then the array of row counts returned is incorrect. For a successful insert, the row count should always be 1. In PreparedStatement#executeBatchInserts(int), it is updating the row count array using the contents of updateCountRunningTotal, which is incorrect.
The problem here is that when the MySQL JDBC connector is used with Hibernate, the row counts returns from executeBatch are validated, which causes problems.
The short term workaround is to turn off rewriteBatchStatements, but this has undesirable performance implications.
How to repeat:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Test {
private final static String CONNECTION_STRING = "jdbc:mysql://localhost:3306/xxx?rewriteBatchedStatements=true";
private final static String USER = "xxx";
private final static String PASSWORD = "xxx";
private final static String SQL = "insert into t1 (id, x) values (?, ?)";
private final static int BATCH_SIZE = 20;
public static void main(String[] args) throws SQLException {
Connection connection = DriverManager.getConnection(CONNECTION_STRING, USER, PASSWORD);
connection.setAutoCommit(false);
PreparedStatement ps = connection.prepareStatement(SQL);
for (int i = 0; i < BATCH_SIZE; i++) {
ps.setInt(1, i);
ps.setInt(2, 42);
ps.addBatch();
}
int[] rowCounts = ps.executeBatch();
for (int i = 0; i < BATCH_SIZE; i++) {
assert rowCounts[i] == 1;
}
}
}
Suggested fix:
In com.mysql.jdbc.PreparedStatement#executeBatchedInserts, set each element of the result to 1 instead of updateCountRunningTotal.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.039 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: If you execute batched inserts with rewriteBatchedStatements=true set on the connection, then the array of row counts returned is incorrect. For a successful insert, the row count should always be 1. In PreparedStatement#executeBatchInserts(int), it is updating the row count array using the contents of updateCountRunningTotal, which is incorrect. The problem here is that when the MySQL JDBC connector is used with Hibernate, the row counts returns from executeBatch are validated, which causes problems. The short term workaround is to turn off rewriteBatchStatements, but this has undesirable performance implications. How to repeat: import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class Test { private final static String CONNECTION_STRING = "jdbc:mysql://localhost:3306/xxx?rewriteBatchedStatements=true"; private final static String USER = "xxx"; private final static String PASSWORD = "xxx"; private final static String SQL = "insert into t1 (id, x) values (?, ?)"; private final static int BATCH_SIZE = 20; public static void main(String[] args) throws SQLException { Connection connection = DriverManager.getConnection(CONNECTION_STRING, USER, PASSWORD); connection.setAutoCommit(false); PreparedStatement ps = connection.prepareStatement(SQL); for (int i = 0; i < BATCH_SIZE; i++) { ps.setInt(1, i); ps.setInt(2, 42); ps.addBatch(); } int[] rowCounts = ps.executeBatch(); for (int i = 0; i < BATCH_SIZE; i++) { assert rowCounts[i] == 1; } } } Suggested fix: In com.mysql.jdbc.PreparedStatement#executeBatchedInserts, set each element of the result to 1 instead of updateCountRunningTotal.