Mysql PreparedStatement上的ArrayIndexOutOfBoundsException ExecuteBatch()
我正在使用preparedStatements和ExecuteBatch向数据库添加483个对象。 当我运行此代码时,所有对象都正确添加到数据库中,但一段时间后程序抛出:Mysql PreparedStatement上的ArrayIndexOutOfBoundsException ExecuteBatch(),mysql,jdbc,prepared-statement,Mysql,Jdbc,Prepared Statement,我正在使用preparedStatements和ExecuteBatch向数据库添加483个对象。 当我运行此代码时,所有对象都正确添加到数据库中,但一段时间后程序抛出: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 484 at com.mysql.jdbc.StatementImpl.processMultiCountsAndKeys(StatementImpl.java:1417) at com.m
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 484
at com.mysql.jdbc.StatementImpl.processMultiCountsAndKeys(StatementImpl.java:1417)
at com.mysql.jdbc.PreparedStatement.executePreparedBatchAsMultiStatement(PreparedStatement.java:1515)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1389)
at model.database.SQLCommand.insertMeasurements(SQLCommand.java:110)
at model.database.SQLCommand.addDatasetToDb(SQLCommand.java:31)
at tests.readText.main(readText.java:35)
这是我的密码:
private static List<Long> insertMeasurements(List<Measurement> measurements, long did) throws SQLException {
conn.setAutoCommit(false);
List<Long> mids = new ArrayList<Long>();
String sql = "INSERT INTO doses (CPS, ground, total) VALUES (?, ?, ?);" + " " +
"INSERT INTO places (x, y, z, speed) VALUES (?, ?, ?, ?);" + " " +
"INSERT INTO measurements (time, place, note, dose, id_dataset) VALUES (?, (SELECT MAX(ID) FROM places), ?, (SELECT MAX(ID) FROM doses), ?)";
try (
PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
) {
for(Measurement measurement: measurements) {
ps.clearParameters();
double cps = measurement.getDose().getCps();
double ground = measurement.getDose().getGround();
double total = measurement.getDose().getTotal();
ps.setDouble(1, cps);
ps.setDouble(2, ground);
ps.setDouble(3, total);
double x = measurement.getPlace().getX();
double y = measurement.getPlace().getY();
double z = measurement.getPlace().getZ();
double speed = measurement.getPlace().getSpeed();
ps.setDouble(4, x);
ps.setDouble(5, y);
ps.setDouble(6, z);
ps.setDouble(7, speed);
String time = measurement.getDate().toString();
String note = measurement.getNote().toString();
ps.setString(8, time);
ps.setString(9, note);
ps.setObject(10, did);
ps.addBatch();
}
ps.executeBatch();
conn.commit();
ResultSet rs = ps.getGeneratedKeys();
while (rs.next()) {
long id = rs.getLong(1);
mids.add(id);
}
} catch (SQLException e) {
throw new SQLException("Can't add the measurement."+e.toString()+"\n" );
}
return mids;
}
看起来像个bug,请确保您使用的是最新的Connector/J驱动程序,否则请向MySQL报告。但是请注意,尽管MySQL驱动程序支持它,但JDBC标准“正式”不允许将多个语句作为一个语句执行,并且Connector/J中的实现有点粗糙。当您将它们作为一个批执行时,您可能遇到了这样一种情况,因为批被MySQL Connector/J重写为多个语句,而将多个语句重写为多个语句可能有点太多了;你有什么建议来分别执行我的多个语句吗?我看不到访问生成的主键的其他方法。通常我建议使用JDBC生成键功能,但批量执行不需要驱动程序来实现,而且大多数驱动程序都不需要iirc。我将尝试创建3个单独的批,并在每个批上使用生成键功能来提供最后一批的键?感谢您的时间:这看起来就像一个bug,即使在2018年4年后仍然存在:-。我只需要尝试一下捕捉数组索引边界外的感觉