Bug #71528 batch inserts with rewriteBatchedStatements=true returns incorrect row counts
Submitted: 30 Jan 2014 15:20 Modified: 31 Jan 2014 7:42
Reporter: Andy Neilson Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:5.1.28 OS:Any
Assigned to: Assigned Account CPU Architecture:Any

[30 Jan 2014 15:20] Andy Neilson
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.
[31 Jan 2014 7:42] Alexander Soklakov
Hi Andy,

Thank you for reporting.
Actually this is a duplicate of Bug#68562, please proceed with discussion there.