From 06b8ed5bec2a0c6d83e85a658def66907419ddd4 Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Tue, 6 Aug 2024 08:20:09 -0700 Subject: [PATCH 01/10] Added a missing unlock --- .../java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java index 199c15306..e2b710e5a 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java @@ -1762,6 +1762,8 @@ private void getDestinationMetadata() throws SQLServerException { } finally { DESTINATION_COL_METADATA_LOCK.unlock(); } + } else { + DESTINATION_COL_METADATA_LOCK.unlock(); } if (loggerExternal.isLoggable(Level.FINER)) { From b6c5c21a71b0d4e9656a3b86ceac863c365f3218 Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Tue, 6 Aug 2024 09:50:42 -0700 Subject: [PATCH 02/10] Clean up locks as per pr review --- .../microsoft/sqlserver/jdbc/SQLServerBulkCopy.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java index e2b710e5a..07390d036 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java @@ -1742,10 +1742,9 @@ private void getDestinationMetadata() throws SQLServerException { if (null == destColumnMetadata || destColumnMetadata.isEmpty()) { if (connection.getcacheBulkCopyMetadata()) { DESTINATION_COL_METADATA_LOCK.lock(); - destColumnMetadata = BULK_COPY_OPERATION_CACHE.get(key); - - if (null == destColumnMetadata || destColumnMetadata.isEmpty()) { - try { + try { + destColumnMetadata = BULK_COPY_OPERATION_CACHE.get(key); + if (null == destColumnMetadata || destColumnMetadata.isEmpty()) { setDestinationColumnMetadata(escapedDestinationTableName); // We are caching the following metadata about the table: @@ -1759,10 +1758,8 @@ private void getDestinationMetadata() throws SQLServerException { // scenario, we can't detect this without making an additional metadata query, which would // defeat the purpose of caching. BULK_COPY_OPERATION_CACHE.put(key, destColumnMetadata); - } finally { - DESTINATION_COL_METADATA_LOCK.unlock(); } - } else { + } finally { DESTINATION_COL_METADATA_LOCK.unlock(); } From ecc73ef7383bbba1a76743449416b835490f1aa5 Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Wed, 7 Aug 2024 14:22:18 -0700 Subject: [PATCH 03/10] Added test --- .../unit/statement/BatchExecutionTest.java | 66 +++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java index 00e99a0f7..18f24cc91 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java @@ -7,8 +7,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assume.assumeTrue; import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import java.lang.reflect.Field; @@ -27,8 +27,12 @@ import java.util.Calendar; import java.util.HashMap; import java.util.TimeZone; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; -import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Tag; @@ -39,6 +43,7 @@ import com.microsoft.sqlserver.jdbc.RandomUtil; import com.microsoft.sqlserver.jdbc.SQLServerConnection; +import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement; import com.microsoft.sqlserver.jdbc.SQLServerStatement; import com.microsoft.sqlserver.jdbc.TestResource; import com.microsoft.sqlserver.jdbc.TestUtils; @@ -147,8 +152,8 @@ public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); long ms = 1578743412000L; - try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection( - connectionString + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); + try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString + + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); Statement stmt = con.createStatement()) { // Needs to be on a JDK version greater than 8 @@ -206,6 +211,59 @@ public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { } } + @Test + public void testSqlServerBulkCopyCachingConnectionLevelMultiThreaded() throws Exception { + Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + long ms = 1578743412000L; + long timeOut = 20000; // 20 seconds + int NUMBER_SIMULTANEOUS_INSERTS = 40; + + try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString + + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); + Statement stmt = con.createStatement()) { + + // Needs to be on a JDK version greater than 8 + assumeTrue(TestUtils.getJVMVersion() > 8); + + TestUtils.dropTableIfExists(timestampTable1, stmt); + String createSqlTable1 = "CREATE TABLE " + timestampTable1 + " (c1 DATETIME2(3))"; + stmt.execute(createSqlTable1); + + TimerTask task = new TimerTask() { + public void run() { + fail(TestResource.getResource("R_executionTooLong")); + } + }; + Timer timer = new Timer("Timer"); + timer.schedule(task, timeOut); // Run a timer to help us exit if we get deadlocked + + final CountDownLatch countDownLatch = new CountDownLatch(NUMBER_SIMULTANEOUS_INSERTS); + Runnable runnable = () -> { + try { + for (int i = 0; i < 5; ++i) { + PreparedStatement preparedStatement = con + .prepareStatement("INSERT INTO " + timestampTable1 + " VALUES(?)"); + Timestamp timestamp = new Timestamp(ms); + preparedStatement.setTimestamp(1, timestamp, gmtCal); + preparedStatement.addBatch(); + preparedStatement.executeBatch(); + } + countDownLatch.countDown(); + countDownLatch.await(); + } catch (Exception e) { + fail(TestResource.getResource("R_unexpectedException") + e.getMessage()); + } + }; + + try (ExecutorService executor = Executors.newFixedThreadPool(NUMBER_SIMULTANEOUS_INSERTS)) { + for (int i = 0; i < NUMBER_SIMULTANEOUS_INSERTS; i++) { + executor.submit(runnable); + } + executor.shutdown(); + } + } + } + @Test public void testValidTimezoneForTimestampBatchInsertWithBulkCopy() throws Exception { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); From 5efb69c824ca90bbb60f7783656f6f11d6f82c5f Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Wed, 7 Aug 2024 14:32:41 -0700 Subject: [PATCH 04/10] Resolve codeql error --- .../sqlserver/jdbc/unit/statement/BatchExecutionTest.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java index 18f24cc91..d1ac77097 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java @@ -255,11 +255,15 @@ public void run() { } }; - try (ExecutorService executor = Executors.newFixedThreadPool(NUMBER_SIMULTANEOUS_INSERTS)) { + ExecutorService executor = Executors.newFixedThreadPool(NUMBER_SIMULTANEOUS_INSERTS); + + try { for (int i = 0; i < NUMBER_SIMULTANEOUS_INSERTS; i++) { executor.submit(runnable); } executor.shutdown(); + } catch (Exception e) { + fail(TestResource.getResource("R_unexpectedException") + e.getMessage()); } } } From 28175d896fe668bb86170565846a4fd796c54075 Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Wed, 7 Aug 2024 18:03:59 -0700 Subject: [PATCH 05/10] Extend timeout time --- .../sqlserver/jdbc/unit/statement/BatchExecutionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java index d1ac77097..3faa63fda 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java @@ -215,7 +215,7 @@ public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { public void testSqlServerBulkCopyCachingConnectionLevelMultiThreaded() throws Exception { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); long ms = 1578743412000L; - long timeOut = 20000; // 20 seconds + long timeOut = 90000; // 90 seconds int NUMBER_SIMULTANEOUS_INSERTS = 40; try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString From 4d782f28c65fae2b32e05a16dc7377fefb35338b Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Wed, 7 Aug 2024 18:56:52 -0700 Subject: [PATCH 06/10] Removing test to narrow down on pipeline failures --- .../unit/statement/BatchExecutionTest.java | 56 ------------------- 1 file changed, 56 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java index 3faa63fda..d0547c692 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java @@ -211,62 +211,6 @@ public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { } } - @Test - public void testSqlServerBulkCopyCachingConnectionLevelMultiThreaded() throws Exception { - Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - long ms = 1578743412000L; - long timeOut = 90000; // 90 seconds - int NUMBER_SIMULTANEOUS_INSERTS = 40; - - try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString - + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); - Statement stmt = con.createStatement()) { - - // Needs to be on a JDK version greater than 8 - assumeTrue(TestUtils.getJVMVersion() > 8); - - TestUtils.dropTableIfExists(timestampTable1, stmt); - String createSqlTable1 = "CREATE TABLE " + timestampTable1 + " (c1 DATETIME2(3))"; - stmt.execute(createSqlTable1); - - TimerTask task = new TimerTask() { - public void run() { - fail(TestResource.getResource("R_executionTooLong")); - } - }; - Timer timer = new Timer("Timer"); - timer.schedule(task, timeOut); // Run a timer to help us exit if we get deadlocked - - final CountDownLatch countDownLatch = new CountDownLatch(NUMBER_SIMULTANEOUS_INSERTS); - Runnable runnable = () -> { - try { - for (int i = 0; i < 5; ++i) { - PreparedStatement preparedStatement = con - .prepareStatement("INSERT INTO " + timestampTable1 + " VALUES(?)"); - Timestamp timestamp = new Timestamp(ms); - preparedStatement.setTimestamp(1, timestamp, gmtCal); - preparedStatement.addBatch(); - preparedStatement.executeBatch(); - } - countDownLatch.countDown(); - countDownLatch.await(); - } catch (Exception e) { - fail(TestResource.getResource("R_unexpectedException") + e.getMessage()); - } - }; - - ExecutorService executor = Executors.newFixedThreadPool(NUMBER_SIMULTANEOUS_INSERTS); - - try { - for (int i = 0; i < NUMBER_SIMULTANEOUS_INSERTS; i++) { - executor.submit(runnable); - } - executor.shutdown(); - } catch (Exception e) { - fail(TestResource.getResource("R_unexpectedException") + e.getMessage()); - } - } - } @Test public void testValidTimezoneForTimestampBatchInsertWithBulkCopy() throws Exception { From f741762901d42fbddabf2c4dbe42b3d5debfb3c1 Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Thu, 8 Aug 2024 09:02:13 -0700 Subject: [PATCH 07/10] Adding a clear to see if this fixes prior errors --- .../unit/statement/BatchExecutionTest.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java index d0547c692..e230e463f 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java @@ -211,6 +211,81 @@ public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { } } + @Test + public void testSqlServerBulkCopyCachingConnectionLevelMultiThreaded() throws Exception { + Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + long ms = 1578743412000L; + long timeOut = 90000; // 90 seconds + int NUMBER_SIMULTANEOUS_INSERTS = 40; + + try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString + + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); + Statement stmt = con.createStatement()) { + + // Needs to be on a JDK version greater than 8 + assumeTrue(TestUtils.getJVMVersion() > 8); + + TestUtils.dropTableIfExists(timestampTable1, stmt); + String createSqlTable1 = "CREATE TABLE " + timestampTable1 + " (c1 DATETIME2(3))"; + stmt.execute(createSqlTable1); + + Field bulkcopyMetadataCacheField; + + if (con.getClass().getName().equals("com.microsoft.sqlserver.jdbc.SQLServerConnection43")) { + bulkcopyMetadataCacheField = con.getClass().getSuperclass() + .getDeclaredField("BULK_COPY_OPERATION_CACHE"); + } else { + bulkcopyMetadataCacheField = con.getClass().getDeclaredField("BULK_COPY_OPERATION_CACHE"); + } + + bulkcopyMetadataCacheField.setAccessible(true); + Object bulkcopyCache = bulkcopyMetadataCacheField.get(con); + + ((HashMap) bulkcopyCache).clear(); + + TimerTask task = new TimerTask() { + public void run() { + ((HashMap) bulkcopyCache).clear(); + fail(TestResource.getResource("R_executionTooLong")); + } + }; + Timer timer = new Timer("Timer"); + timer.schedule(task, timeOut); // Run a timer to help us exit if we get deadlocked + + final CountDownLatch countDownLatch = new CountDownLatch(NUMBER_SIMULTANEOUS_INSERTS); + Runnable runnable = () -> { + try { + for (int i = 0; i < 5; ++i) { + PreparedStatement preparedStatement = con + .prepareStatement("INSERT INTO " + timestampTable1 + " VALUES(?)"); + Timestamp timestamp = new Timestamp(ms); + preparedStatement.setTimestamp(1, timestamp, gmtCal); + preparedStatement.addBatch(); + preparedStatement.executeBatch(); + } + countDownLatch.countDown(); + countDownLatch.await(); + } catch (Exception e) { + fail(TestResource.getResource("R_unexpectedException") + e.getMessage()); + } finally { + ((HashMap) bulkcopyCache).clear(); + } + }; + + ExecutorService executor = Executors.newFixedThreadPool(NUMBER_SIMULTANEOUS_INSERTS); + + try { + for (int i = 0; i < NUMBER_SIMULTANEOUS_INSERTS; i++) { + executor.submit(runnable); + } + executor.shutdown(); + } catch (Exception e) { + fail(TestResource.getResource("R_unexpectedException") + e.getMessage()); + } finally { + ((HashMap) bulkcopyCache).clear(); + } + } + } @Test public void testValidTimezoneForTimestampBatchInsertWithBulkCopy() throws Exception { From 296bb0213091234bf5cc8ba911635b072a71e94b Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Tue, 13 Aug 2024 08:57:48 -0700 Subject: [PATCH 08/10] PR review changes --- .../jdbc/unit/statement/BatchExecutionTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java index e230e463f..5efb33785 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java @@ -152,13 +152,13 @@ public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); long ms = 1578743412000L; + // Needs to be on a JDK version greater than 8 + assumeTrue(TestUtils.getJVMVersion() > 8); + try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); Statement stmt = con.createStatement()) { - // Needs to be on a JDK version greater than 8 - assumeTrue(TestUtils.getJVMVersion() > 8); - TestUtils.dropTableIfExists(timestampTable1, stmt); TestUtils.dropTableIfExists(timestampTable2, stmt); String createSqlTable1 = "CREATE TABLE " + timestampTable1 + " (c1 DATETIME2(3))"; @@ -215,16 +215,16 @@ public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { public void testSqlServerBulkCopyCachingConnectionLevelMultiThreaded() throws Exception { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); long ms = 1578743412000L; - long timeOut = 90000; // 90 seconds - int NUMBER_SIMULTANEOUS_INSERTS = 40; + long timeOut = 30000; // 30 seconds + int NUMBER_SIMULTANEOUS_INSERTS = 5; + + // Needs to be on a JDK version greater than 8 + assumeTrue(TestUtils.getJVMVersion() > 8); try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); Statement stmt = con.createStatement()) { - // Needs to be on a JDK version greater than 8 - assumeTrue(TestUtils.getJVMVersion() > 8); - TestUtils.dropTableIfExists(timestampTable1, stmt); String createSqlTable1 = "CREATE TABLE " + timestampTable1 + " (c1 DATETIME2(3))"; stmt.execute(createSqlTable1); From 4b89d7c609eb94020e3ed456f348a781e4d59737 Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Mon, 19 Aug 2024 14:16:16 -0700 Subject: [PATCH 09/10] Address PR comments --- .../jdbc/unit/statement/BatchExecutionTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java index 5efb33785..1cc400fc7 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java @@ -149,12 +149,12 @@ public void testSqlServerBulkCopyCachingPstmtLevel() throws Exception { @Test public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { - Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); - long ms = 1578743412000L; - // Needs to be on a JDK version greater than 8 assumeTrue(TestUtils.getJVMVersion() > 8); + Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + long ms = 1578743412000L; + try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); Statement stmt = con.createStatement()) { @@ -213,14 +213,14 @@ public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { @Test public void testSqlServerBulkCopyCachingConnectionLevelMultiThreaded() throws Exception { + // Needs to be on a JDK version greater than 8 + assumeTrue(TestUtils.getJVMVersion() > 8); + Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); long ms = 1578743412000L; - long timeOut = 30000; // 30 seconds + long timeOut = 30000; int NUMBER_SIMULTANEOUS_INSERTS = 5; - // Needs to be on a JDK version greater than 8 - assumeTrue(TestUtils.getJVMVersion() > 8); - try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); Statement stmt = con.createStatement()) { From 1c0ff80c1228c2fc5cde28634077f5f4b3a5a9a1 Mon Sep 17 00:00:00 2001 From: Jeff Wasty Date: Mon, 19 Aug 2024 14:43:57 -0700 Subject: [PATCH 10/10] More --- .../microsoft/sqlserver/jdbc/SQLServerBulkCopy.java | 1 + .../jdbc/unit/statement/BatchExecutionTest.java | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java index 07390d036..74619a893 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java @@ -1744,6 +1744,7 @@ private void getDestinationMetadata() throws SQLServerException { DESTINATION_COL_METADATA_LOCK.lock(); try { destColumnMetadata = BULK_COPY_OPERATION_CACHE.get(key); + if (null == destColumnMetadata || destColumnMetadata.isEmpty()) { setDestinationColumnMetadata(escapedDestinationTableName); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java index 1cc400fc7..0776d4b46 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/BatchExecutionTest.java @@ -149,16 +149,16 @@ public void testSqlServerBulkCopyCachingPstmtLevel() throws Exception { @Test public void testSqlServerBulkCopyCachingConnectionLevel() throws Exception { - // Needs to be on a JDK version greater than 8 - assumeTrue(TestUtils.getJVMVersion() > 8); - Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); long ms = 1578743412000L; - try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection(connectionString - + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); + try (SQLServerConnection con = (SQLServerConnection) DriverManager.getConnection( + connectionString + ";useBulkCopyForBatchInsert=true;cacheBulkCopyMetadata=true;sendTemporalDataTypesAsStringForBulkCopy=false;"); Statement stmt = con.createStatement()) { + // Needs to be on a JDK version greater than 8 + assumeTrue(TestUtils.getJVMVersion() > 8); + TestUtils.dropTableIfExists(timestampTable1, stmt); TestUtils.dropTableIfExists(timestampTable2, stmt); String createSqlTable1 = "CREATE TABLE " + timestampTable1 + " (c1 DATETIME2(3))";