Reputation: 5138
I am trying to insert some data from excel file into a table. I have two excel file as follows:
Test2:
5/12/2012 5/18/2012 ABQ ANC 1 52
5/12/2012 5/18/2012 ABQ ANC 2 30
5/12/2012 5/18/2012 ABQ ANC 3 34
5/12/2012 5/18/2012 ABQ ANC 4 41
5/12/2012 5/18/2012 ABQ ANC 5 53--->duplicate row
5/12/2012 5/18/2012 ABQ ANC 6 18
5/12/2012 5/18/2012 ABQ ANC 7 4
5/12/2012 5/18/2012 ABQ ATL 1 389
5/12/2012 5/18/2012 ABQ ATL 2 312
test1:
5/12/2012 5/18/2012 ABQ ATL 4 259
5/12/2012 5/18/2012 ABQ ATL 5 362
5/12/2012 5/18/2012 ABQ ATL 6 240
5/12/2012 5/18/2012 ABQ ATL 7 88
5/12/2012 5/18/2012 ABQ ANC 5 53--->duplicate row
5/12/2012 5/18/2012 ABQ AUS 2 2
5/12/2012 5/18/2012 ABQ BDL 1 164
5/12/2012 5/18/2012 ABQ BDL 2 128
5/12/2012 5/18/2012 ABQ BDL 3 132
My table, to start with is, empty. So I insert the first file(test2), it works fine. When inserting 2nd file(test1), it should give "Unique constraint violated" exception at row 5 of test1. I duplicated that row on purpose for testing. I wrote the following code to do the inserts. As you can see the batch size is 3.
When inserting second file, The code executes the first batch(which is the first 3 rows) fine. In the second batch(row 4-6), because one of the row(5) is duplicated, it throws BatchUpdatException. I catch that exception and in the catch block, I process each row(row 4-6) one at a time. So the insert for row 4 should have worked fine. But it doesn't. It instead throws an sqlException. Row 5 throws exception as well(duplicate row). But row 6 doesn't. Row 6 executeUpdate() runs fine. At this point if I look at my database table, I see that row 4 is also inserted into the table along with the row 6. How can this happen, it just threw ane exception at row 4?
My objective is to let the user know where the duplicate rows are. Because of this aberrant behavior, the user is told that there is a duplicate row in row 4 and row 5 when they try to insert the second file.
String sqlStatement = "INSERT INTO DMD_VOL_UPLOAD (ORIGIN, DESTINATION, DAY_OF_WEEK, EFFECTIVE_DATE, DISCONTINUE_DATE, VOLUME)";
int batchSize=3;
sqlStatement += " VALUES(?, ?, ?, ?, ?, ?)";
con = session.connection();
pstmt = con.prepareStatement(sqlStatement);
for(currentRow=1; currentRow<=rowCount; currentRow++){
try{
forecastBatch = (ForecastBatch) list.get(currentRow-1);
pstmt = (PreparedStatement) prepareStatement(pstmt, forecastBatch);
pstmt.addBatch();
if(currentRow % batchSize == 0 || currentRow==rowCount){
updateCounts = pstmt.executeBatch();
con.commit();
pstmt.clearBatch();
}
}catch(BatchUpdateException e){
int endPoint = currentRow;
int i;
for(i=currentRow-batchSize; i<endPoint; i++){
forecastBatch = (ForecastBatch) list.get(i);
try{
pstmt = (PreparedStatement) prepareStatement(pstmt, forecastBatch);
pstmt.executeUpdate();**strong text**
con.commit();
}catch(SQLException ex){
errorRowNum = errorRowNum + (i+1) + ", ";
ex.printStackTrace();
}
}
}catch(SQLException e){
e.printStackTrace();
}
}//end of the first for loop
Upvotes: 0
Views: 2420
Reputation: 231661
When you executeBatch
a batch of statements, some of the statements may succeed and some of the statements may fail. If one statement fails, that does not mean that the JDBC driver rolls back the statements that succeeded. The JDBC driver may choose to attempt to execute all the statements in the batch if one statement fails or it may choose to stop executing statements in the batch once a statement fails (it sounds like the driver you're using chooses to stop executing statements as soon as there is a failure).
When you get a BatchUpdateException
, you need to call getUpdateCounts
. That will give you an array of int
that tells you either how many rows the statement updated, a Statement.SUCCESS_NO_INFO
indicating the statement succeeded but no row count was available, or a Statement.EXECUTE_FAILED
indicating that the statement failed. I would expect that you would get back a two element array indicating that the first statement in the batch (row 4 in the spreadsheet) succeeded and that the second statement in the batch (row 5 in the spreadsheet) failed. The lack of a third element in the array would indicate that the third statement in the batch (row 6 in the spreadsheet) was not executed. Your retry code would need to retry only the statements that were not executed. In this case, only the third statement (row 6 in the spreadsheet) would need to be retried because the BatchUpdateException
already tells you that the first statement succeeded and the second statement failed.
Upvotes: 1