Fall back to plain setObject call for non-supported SQL type
Closes gh-30556
This commit is contained in:
parent
4b8adf2dcc
commit
d2906253f1
|
@ -25,6 +25,7 @@ import java.sql.Clob;
|
|||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
@ -84,7 +85,7 @@ public abstract class StatementCreatorUtils {
|
|||
|
||||
private static final Log logger = LogFactory.getLog(StatementCreatorUtils.class);
|
||||
|
||||
private static final Map<Class<?>, Integer> javaTypeToSqlTypeMap = new HashMap<>(32);
|
||||
private static final Map<Class<?>, Integer> javaTypeToSqlTypeMap = new HashMap<>(64);
|
||||
|
||||
static {
|
||||
javaTypeToSqlTypeMap.put(boolean.class, Types.BOOLEAN);
|
||||
|
@ -106,8 +107,8 @@ public abstract class StatementCreatorUtils {
|
|||
javaTypeToSqlTypeMap.put(LocalDate.class, Types.DATE);
|
||||
javaTypeToSqlTypeMap.put(LocalTime.class, Types.TIME);
|
||||
javaTypeToSqlTypeMap.put(LocalDateTime.class, Types.TIMESTAMP);
|
||||
javaTypeToSqlTypeMap.put(OffsetDateTime.class, Types.TIMESTAMP_WITH_TIMEZONE);
|
||||
javaTypeToSqlTypeMap.put(OffsetTime.class, Types.TIME_WITH_TIMEZONE);
|
||||
javaTypeToSqlTypeMap.put(OffsetDateTime.class, Types.TIMESTAMP_WITH_TIMEZONE);
|
||||
javaTypeToSqlTypeMap.put(java.sql.Date.class, Types.DATE);
|
||||
javaTypeToSqlTypeMap.put(java.sql.Time.class, Types.TIME);
|
||||
javaTypeToSqlTypeMap.put(java.sql.Timestamp.class, Types.TIMESTAMP);
|
||||
|
@ -290,7 +291,19 @@ public abstract class StatementCreatorUtils {
|
|||
ps.setNull(paramIndex, sqlType, typeName);
|
||||
}
|
||||
else {
|
||||
ps.setNull(paramIndex, sqlType);
|
||||
// Fall back to generic setNull call.
|
||||
try {
|
||||
// Try generic setNull call with SQL type specified.
|
||||
ps.setNull(paramIndex, sqlType);
|
||||
}
|
||||
catch (SQLFeatureNotSupportedException ex) {
|
||||
if (sqlType == Types.NULL) {
|
||||
throw ex;
|
||||
}
|
||||
// Fall back to generic setNull call without SQL type specified
|
||||
// (e.g. for MySQL TIME_WITH_TIMEZONE / TIMESTAMP_WITH_TIMEZONE).
|
||||
ps.setNull(paramIndex, Types.NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,8 +428,16 @@ public abstract class StatementCreatorUtils {
|
|||
}
|
||||
}
|
||||
else {
|
||||
// Fall back to generic setObject call with SQL type specified.
|
||||
ps.setObject(paramIndex, inValue, sqlType);
|
||||
// Fall back to generic setObject call.
|
||||
try {
|
||||
// Try generic setObject call with SQL type specified.
|
||||
ps.setObject(paramIndex, inValue, sqlType);
|
||||
}
|
||||
catch (SQLFeatureNotSupportedException ex) {
|
||||
// Fall back to generic setObject call without SQL type specified
|
||||
// (e.g. for MySQL TIME_WITH_TIMEZONE / TIMESTAMP_WITH_TIMEZONE).
|
||||
ps.setObject(paramIndex, inValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,10 +21,12 @@ import java.sql.DatabaseMetaData;
|
|||
import java.sql.ParameterMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.sql.Types;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -36,6 +38,7 @@ import org.junit.jupiter.params.provider.MethodSource;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Named.named;
|
||||
import static org.mockito.BDDMockito.doThrow;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
|
@ -213,7 +216,6 @@ public class StatementCreatorUtilsTests {
|
|||
verify(preparedStatement).setTimestamp(1, new java.sql.Timestamp(cal.getTime().getTime()), cal);
|
||||
}
|
||||
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("javaTimeTypes")
|
||||
public void testSetParameterValueWithJavaTimeTypes(Object o, int sqlType) throws SQLException {
|
||||
|
@ -242,6 +244,23 @@ public class StatementCreatorUtilsTests {
|
|||
);
|
||||
}
|
||||
|
||||
@Test // gh-30556
|
||||
public void testSetParameterValueWithOffsetDateTimeAndNotSupported() throws SQLException {
|
||||
OffsetDateTime time = OffsetDateTime.now();
|
||||
doThrow(new SQLFeatureNotSupportedException()).when(preparedStatement).setObject(1, time, Types.TIMESTAMP_WITH_TIMEZONE);
|
||||
StatementCreatorUtils.setParameterValue(preparedStatement, 1, Types.TIMESTAMP_WITH_TIMEZONE, null, time);
|
||||
verify(preparedStatement).setObject(1, time, Types.TIMESTAMP_WITH_TIMEZONE);
|
||||
verify(preparedStatement).setObject(1, time);
|
||||
}
|
||||
|
||||
@Test // gh-30556
|
||||
public void testSetParameterValueWithNullAndNotSupported() throws SQLException {
|
||||
doThrow(new SQLFeatureNotSupportedException()).when(preparedStatement).setNull(1, Types.TIMESTAMP_WITH_TIMEZONE);
|
||||
StatementCreatorUtils.setParameterValue(preparedStatement, 1, Types.TIMESTAMP_WITH_TIMEZONE, null, null);
|
||||
verify(preparedStatement).setNull(1, Types.TIMESTAMP_WITH_TIMEZONE);
|
||||
verify(preparedStatement).setNull(1, Types.NULL);
|
||||
}
|
||||
|
||||
@Test // SPR-8571
|
||||
public void testSetParameterValueWithStringAndVendorSpecificType() throws SQLException {
|
||||
Connection con = mock();
|
||||
|
|
Loading…
Reference in New Issue