1+ package de .bytefish .jsqlserverbulkinsert .test ;
2+
3+ import org .junit .jupiter .api .BeforeEach ;
4+ import org .junit .jupiter .api .Test ;
5+ import org .junit .jupiter .api .TestInstance ;
6+
7+ import java .sql .Connection ;
8+ import java .sql .DriverManager ;
9+ import java .sql .Statement ;
10+ import java .util .ArrayList ;
11+ import java .util .List ;
12+ import java .util .UUID ;
13+ import java .util .concurrent .atomic .AtomicInteger ;
14+ import java .util .concurrent .atomic .AtomicLong ;
15+ import java .util .concurrent .atomic .AtomicReference ;
16+
17+ import static de .bytefish .jsqlserverbulkinsert .SqlServerBulkInsert .*;
18+ import static org .junit .jupiter .api .Assertions .*;
19+
20+ @ TestInstance (TestInstance .Lifecycle .PER_CLASS )
21+ public class SqlServerBulkInsertErrorHandlerTest {
22+
23+ private static final String CONNECTION_STRING =
24+ "jdbc:sqlserver://localhost:14330;databaseName=master;user=sa;password=MyStrongPassw0rd;trustServerCertificate=true;" ;
25+
26+ record ErrorEntity (UUID id , String name ) {}
27+
28+ private static final SqlServerMapper <ErrorEntity > MAPPER = SqlServerMapper .forClass (ErrorEntity .class )
29+ .map ("Id" , SqlServerTypes .UNIQUEIDENTIFIER .from (ErrorEntity ::id ))
30+ .map ("Name" , SqlServerTypes .NVARCHAR .from (ErrorEntity ::name ));
31+
32+ @ BeforeEach
33+ public void setupTable () throws Exception {
34+ try (Connection conn = DriverManager .getConnection (CONNECTION_STRING );
35+ Statement stmt = conn .createStatement ()) {
36+ stmt .execute ("IF OBJECT_ID('dbo.ErrorTestTable', 'U') IS NOT NULL DROP TABLE dbo.ErrorTestTable;" );
37+ stmt .execute ("CREATE TABLE dbo.ErrorTestTable (Id UNIQUEIDENTIFIER PRIMARY KEY, Name NVARCHAR(255));" );
38+ }
39+ }
40+
41+ @ Test
42+ public void testErrorHandlerCapturesConstraintViolation () throws Exception {
43+ // Arrange: Prepare data with a duplicate ID to trigger a Primary Key violation
44+ UUID duplicateId = UUID .randomUUID ();
45+ List <ErrorEntity > data = List .of (
46+ new ErrorEntity (duplicateId , "First" ),
47+ new ErrorEntity (duplicateId , "Duplicate" )
48+ );
49+
50+ AtomicReference <Exception > capturedException = new AtomicReference <>();
51+
52+ SqlServerBulkWriter <ErrorEntity > writer = new SqlServerBulkWriter <>(MAPPER )
53+ .withErrorHandler (capturedException ::set );
54+
55+ // Act
56+ try (Connection conn = DriverManager .getConnection (CONNECTION_STRING )) {
57+ BulkInsertResult result = writer .saveAll (conn , "dbo" , "ErrorTestTable" , data );
58+
59+ // Assert
60+ assertFalse (result .success (), "Bulk insert should fail due to PK violation" );
61+ assertNotNull (capturedException .get (), "Error handler should have captured the exception" );
62+ assertTrue (capturedException .get ().getMessage ().contains ("Violation of PRIMARY KEY constraint" ),
63+ "Exception message should indicate PK violation" );
64+ }
65+ }
66+
67+ @ Test
68+ public void testErrorHandlerCapturesMissingTableError () throws Exception {
69+ // Arrange
70+ List <ErrorEntity > data = List .of (new ErrorEntity (UUID .randomUUID (), "Test" ));
71+ AtomicReference <Exception > capturedException = new AtomicReference <>();
72+
73+ SqlServerBulkWriter <ErrorEntity > writer = new SqlServerBulkWriter <>(MAPPER )
74+ .withErrorHandler (capturedException ::set );
75+
76+ // Act
77+ try (Connection conn = DriverManager .getConnection (CONNECTION_STRING )) {
78+ // Try to insert into a non-existing table
79+ BulkInsertResult result = writer .saveAll (conn , "dbo" , "NonExistingTable" , data );
80+
81+ // Assert
82+ assertFalse (result .success ());
83+ assertNotNull (capturedException .get ());
84+ assertTrue (capturedException .get ().getCause ().getMessage ().contains ("Invalid object name" ),
85+ "Exception message should indicate missing table" );
86+ }
87+ }
88+ }
0 commit comments