From ff950a9cc5e989b65fb4dbe4602f1f0d341da7bd Mon Sep 17 00:00:00 2001
From: smagic <1976648487@qq.com>
Date: Sat, 18 May 2024 10:21:19 +0800
Subject: [PATCH] Fixed the problem that when the jdbc type is Array and
 Array.free() is called, the log parameter printed by BaseJdbcLogger is null.

---
 .../ibatis/logging/jdbc/BaseJdbcLogger.java   | 39 +++++++++----------
 .../logging/jdbc/BaseJdbcLoggerTest.java      | 29 ++++++++++----
 2 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/src/main/java/org/apache/ibatis/logging/jdbc/BaseJdbcLogger.java b/src/main/java/org/apache/ibatis/logging/jdbc/BaseJdbcLogger.java
index b2dd5f5e6dd..cad59d9fddb 100644
--- a/src/main/java/org/apache/ibatis/logging/jdbc/BaseJdbcLogger.java
+++ b/src/main/java/org/apache/ibatis/logging/jdbc/BaseJdbcLogger.java
@@ -15,23 +15,17 @@
  */
 package org.apache.ibatis.logging.jdbc;
 
+import org.apache.ibatis.builder.SqlSourceBuilder;
+import org.apache.ibatis.logging.Log;
+import org.apache.ibatis.reflection.ArrayUtil;
+
 import java.lang.reflect.Method;
 import java.sql.Array;
 import java.sql.PreparedStatement;
 import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 import java.util.stream.Collectors;
 
-import org.apache.ibatis.builder.SqlSourceBuilder;
-import org.apache.ibatis.logging.Log;
-import org.apache.ibatis.reflection.ArrayUtil;
-
 /**
  * Base class for proxies to do logging.
  *
@@ -43,10 +37,10 @@ public abstract class BaseJdbcLogger {
   protected static final Set<String> SET_METHODS;
   protected static final Set<String> EXECUTE_METHODS = new HashSet<>();
 
-  private final Map<Object, Object> columnMap = new HashMap<>();
+  private final Map<Object, String> columnMap = new HashMap<>();
 
   private final List<Object> columnNames = new ArrayList<>();
-  private final List<Object> columnValues = new ArrayList<>();
+  private final List<String> columnValues = new ArrayList<>();
 
   protected final Log statementLog;
   protected final int queryStack;
@@ -75,9 +69,18 @@ public BaseJdbcLogger(Log log, int queryStack) {
   }
 
   protected void setColumn(Object key, Object value) {
-    columnMap.put(key, value);
+    String valueString = null;
+    if (value!=null){
+      valueString = objectValueString(value) +
+        "(" + value.getClass().getSimpleName()+")";
+    } else {
+      valueString = "null";
+    }
+
+
+    columnMap.put(key, valueString);
     columnNames.add(key);
-    columnValues.add(value);
+    columnValues.add(valueString);
   }
 
   protected Object getColumn(Object key) {
@@ -87,11 +90,7 @@ protected Object getColumn(Object key) {
   protected String getParameterValueString() {
     List<Object> typeList = new ArrayList<>(columnValues.size());
     for (Object value : columnValues) {
-      if (value == null) {
-        typeList.add("null");
-      } else {
-        typeList.add(objectValueString(value) + "(" + value.getClass().getSimpleName() + ")");
-      }
+       typeList.add(value);
     }
     final String parameters = typeList.toString();
     return parameters.substring(1, parameters.length() - 1);
diff --git a/src/test/java/org/apache/ibatis/logging/jdbc/BaseJdbcLoggerTest.java b/src/test/java/org/apache/ibatis/logging/jdbc/BaseJdbcLoggerTest.java
index 1d39c7c8eae..fe29f47ed8c 100644
--- a/src/test/java/org/apache/ibatis/logging/jdbc/BaseJdbcLoggerTest.java
+++ b/src/test/java/org/apache/ibatis/logging/jdbc/BaseJdbcLoggerTest.java
@@ -15,11 +15,6 @@
  */
 package org.apache.ibatis.logging.jdbc;
 
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.when;
-
-import java.sql.Array;
-
 import org.apache.ibatis.logging.Log;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -27,12 +22,18 @@
 import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
+import java.sql.Array;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+
 @ExtendWith(MockitoExtension.class)
 class BaseJdbcLoggerTest {
 
   @Mock
   Log log;
-  @Mock
+  @Mock(strictness = Mock.Strictness.LENIENT)
   Array array;
   private BaseJdbcLogger logger;
 
@@ -44,15 +45,29 @@ void setUp() {
 
   @Test
   void shouldDescribePrimitiveArrayParameter() throws Exception {
-    logger.setColumn("1", array);
     when(array.getArray()).thenReturn(new int[] { 1, 2, 3 });
+    logger.setColumn("1", array);
     assertThat(logger.getParameterValueString()).startsWith("[1, 2, 3]");
   }
 
   @Test
   void shouldDescribeObjectArrayParameter() throws Exception {
+    when(array.getArray()).thenReturn(new String[] { "one", "two", "three" });
     logger.setColumn("1", array);
+    assertThat(logger.getParameterValueString()).startsWith("[one, two, three]");
+  }
+
+  @Test
+  void shouldDescribeObjectArrayCallFreeParameter() throws Exception {
+
     when(array.getArray()).thenReturn(new String[] { "one", "two", "three" });
+    logger.setColumn("1", array);
+    doAnswer(e->{
+      when(array.getArray()).thenReturn(null);
+      return null;
+    }).when(array).free();
+    array.free();
     assertThat(logger.getParameterValueString()).startsWith("[one, two, three]");
+
   }
 }