SQL batch insert incorrectly flagging last element of list as duplicate key

57 views Asked by At

The table in M$ SQL Server 2019 15.0.4.4335.1

CREATE TABLE foo (
    id bigint IDENTITY (1,1) NOT NULL
    , last_name nvarchar(255) NOT NULL
    , first_name nvarchar(255) NOT NULL
    , middle_name nvarchar(255)
     PRIMARY KEY (id)
    , CONSTRAINT PK_FULL_NAME UNIQUE ( last_name, first_name, middle_name)
);

which corresponds with class Foo.

in Java 8 I read in a tab in a spreadsheet using Apache POI to populate a List<Foo> list_foo. So far so good.

I then try to populate the table with the list using

try {
    String sqlCmd = "INSERT INTO foo VALUES (?,?,?)";
    PreparedStatement stmt = connect.prepareStatement( sqlCmd);
    ListIterator<Foo> li = list_foo.listIterator();
    while( li.hasNext()) {
        Foo obj = li.next();
        stmt.setString( 1, obj.getLastName());
        stmt.setString( 2, obj.getFirstName());
        stmt.setString( 3, obj.getMiddleName());
        stmt.addBatch();
    }
    int[] insr_cnt = stmt.executeBatch()
    connect.commit();
    System.out.println( "rows inserted: " + insr_cnt);
} catch ( java.sql.BatchUpdateException e) {
    e.printStackTrace();            // this gets thrown, see below
} catch ( SQLException e) {
    e.printStackTrace();  
} catch ( Exception e) {
    e.printStackTrace();  
}

this throws a:

Violation of UNIQUE KEY constraint PK_FULL_NAME UNIQUE . Cannot insert duplicate key ( 'Williams','Wendy','Ophelia' ).

Sounds pretty straight-forward. But a visual inspection of the tab shows 1) this is indeed a unique triplet and 2) the last row in the tab.

Just for fun I manually moved this row somewhere in the middle of the tab so 'Pierce','Benjamen','Franklin' became the last row. Executing the code threw same exact error but with PBF as the duplicate.

So it seems there's some subtlety with the code not liking the last row of the tab / last element of list_foo.

Anyone run into this before? And if so what's the solution?

0

There are 0 answers