Skip to content

Commit 4978b4c

Browse files
committed
Polishing.
Correctly assign SQL type for tuples. See #1323 Original pull request: #1838
1 parent f0d3b5e commit 4978b4c

File tree

5 files changed

+42
-14
lines changed

5 files changed

+42
-14
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java

+15-6
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import java.lang.reflect.Array;
2121
import java.lang.reflect.Constructor;
22-
import java.sql.JDBCType;
2322
import java.sql.SQLType;
2423
import java.util.ArrayList;
2524
import java.util.Collection;
@@ -31,8 +30,10 @@
3130
import org.springframework.beans.BeanInstantiationException;
3231
import org.springframework.beans.BeanUtils;
3332
import org.springframework.beans.factory.BeanFactory;
33+
import org.springframework.data.jdbc.core.convert.JdbcColumnTypes;
3434
import org.springframework.data.jdbc.core.convert.JdbcConverter;
3535
import org.springframework.data.jdbc.core.mapping.JdbcValue;
36+
import org.springframework.data.jdbc.support.JdbcUtil;
3637
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
3738
import org.springframework.data.relational.repository.query.RelationalParameterAccessor;
3839
import org.springframework.data.relational.repository.query.RelationalParametersParameterAccessor;
@@ -223,7 +224,7 @@ private JdbcValue writeValue(@Nullable Object value, TypeInformation<?> typeInfo
223224
if (actualType != null && actualType.getType().isArray()) {
224225

225226
TypeInformation<?> nestedElementType = actualType.getRequiredActualType();
226-
return writeCollection(collection, JDBCType.OTHER,
227+
return writeCollection(collection, parameter.getActualSqlType(),
227228
array -> writeArrayValue(parameter, array, nestedElementType));
228229
}
229230

@@ -265,21 +266,29 @@ private JdbcValue writeCollection(Collection<?> value, SQLType defaultType, Func
265266
return jdbcValue;
266267
}
267268

268-
private Object[] writeArrayValue(JdbcParameters.JdbcParameter parameter, Object array,
269+
private JdbcValue writeArrayValue(JdbcParameters.JdbcParameter parameter, Object array,
269270
TypeInformation<?> nestedElementType) {
270271

271272
int length = Array.getLength(array);
272273
Object[] mappedArray = new Object[length];
274+
SQLType sqlType = null;
273275

274276
for (int i = 0; i < length; i++) {
275277

276278
Object element = Array.get(array, i);
277-
JdbcValue elementJdbcValue = converter.writeJdbcValue(element, nestedElementType, parameter.getActualSqlType());
279+
JdbcValue converted = converter.writeJdbcValue(element, nestedElementType, parameter.getActualSqlType());
278280

279-
mappedArray[i] = elementJdbcValue.getValue();
281+
if (sqlType == null && converted.getJdbcType() != null) {
282+
sqlType = converted.getJdbcType();
283+
}
284+
mappedArray[i] = converted.getValue();
285+
}
286+
287+
if (sqlType == null) {
288+
sqlType = JdbcUtil.targetSqlTypeFor(JdbcColumnTypes.INSTANCE.resolvePrimitiveType(nestedElementType.getType()));
280289
}
281290

282-
return mappedArray;
291+
return JdbcValue.of(mappedArray, sqlType);
283292
}
284293

285294
RowMapper<Object> determineRowMapper(ResultProcessor resultProcessor, boolean hasDynamicProjection) {

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/support/JdbcUtil.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,11 @@
2222
import java.sql.SQLType;
2323
import java.sql.Time;
2424
import java.sql.Timestamp;
25-
import java.sql.Types;
2625
import java.time.OffsetDateTime;
2726
import java.util.HashMap;
2827
import java.util.Map;
2928

3029
import org.springframework.jdbc.support.JdbcUtils;
31-
import org.springframework.lang.Nullable;
3230
import org.springframework.util.Assert;
3331

3432
/**
@@ -54,7 +52,12 @@ public String getVendor() {
5452
public Integer getVendorTypeNumber() {
5553
return JdbcUtils.TYPE_UNKNOWN;
5654
}
57-
} ;
55+
56+
@Override
57+
public String toString() {
58+
return getName();
59+
}
60+
};
5861
private static final Map<Class<?>, SQLType> sqlTypeMappings = new HashMap<>();
5962

6063
static {

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java

+13-5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.junit.jupiter.params.ParameterizedTest;
4242
import org.junit.jupiter.params.provider.Arguments;
4343
import org.junit.jupiter.params.provider.MethodSource;
44+
4445
import org.springframework.beans.factory.annotation.Autowired;
4546
import org.springframework.beans.factory.config.PropertiesFactoryBean;
4647
import org.springframework.context.ApplicationListener;
@@ -66,6 +67,7 @@
6667
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
6768
import org.springframework.data.jdbc.testing.ConditionalOnDatabase;
6869
import org.springframework.data.jdbc.testing.DatabaseType;
70+
import org.springframework.data.jdbc.testing.EnabledOnDatabase;
6971
import org.springframework.data.jdbc.testing.EnabledOnFeature;
7072
import org.springframework.data.jdbc.testing.IntegrationTest;
7173
import org.springframework.data.jdbc.testing.TestConfiguration;
@@ -107,6 +109,7 @@
107109
* @author Paul Jones
108110
*/
109111
@IntegrationTest
112+
@EnabledOnDatabase(DatabaseType.MARIADB)
110113
public class JdbcRepositoryIntegrationTests {
111114

112115
@Autowired NamedParameterJdbcTemplate template;
@@ -1339,15 +1342,15 @@ void withDelimitedColumnTest() {
13391342
}
13401343

13411344
@Test // GH-1323
1345+
@EnabledOnFeature(TestDatabaseFeatures.Feature.WHERE_IN_TUPLE)
13421346
void queryWithTupleIn() {
13431347

13441348
DummyEntity one = repository.save(createDummyEntity("one"));
1345-
DummyEntity two = repository.save(createDummyEntity( "two"));
1346-
DummyEntity three = repository.save(createDummyEntity( "three"));
1349+
DummyEntity two = repository.save(createDummyEntity("two"));
1350+
DummyEntity three = repository.save(createDummyEntity("three"));
13471351

1348-
List<Object[]> tuples = List.of(
1349-
new Object[]{two.idProp, "two"}, // matches "two"
1350-
new Object[]{three.idProp, "two"} // matches nothing
1352+
List<Object[]> tuples = List.of(new Object[] { two.idProp, "two" }, // matches "two"
1353+
new Object[] { three.idProp, "two" } // matches nothing
13511354
);
13521355

13531356
List<DummyEntity> result = repository.findByListInTuple(tuples);
@@ -1887,6 +1890,11 @@ public boolean equals(Object o) {
18871890
public int hashCode() {
18881891
return Objects.hash(name, pointInTime, offsetDateTime, idProp, flag, ref, direction);
18891892
}
1893+
1894+
@Override
1895+
public String toString() {
1896+
return "DummyEntity{" + "name='" + name + '\'' + ", idProp=" + idProp + '}';
1897+
}
18901898
}
18911899

18921900
enum Direction {

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.springframework.data.jdbc.core.convert.MappingJdbcConverter;
5050
import org.springframework.data.jdbc.core.convert.RelationResolver;
5151
import org.springframework.data.jdbc.core.mapping.JdbcValue;
52+
import org.springframework.data.jdbc.support.JdbcUtil;
5253
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
5354
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
5455
import org.springframework.data.repository.Repository;
@@ -338,6 +339,8 @@ void queryByListOfTuples() {
338339
assertThat(parameterSource.getValue("tuples"))
339340
.asInstanceOf(LIST)
340341
.containsExactly(tuples);
342+
343+
assertThat(parameterSource.getSqlType("tuples")).isEqualTo(JdbcUtil.TYPE_UNKNOWN.getVendorTypeNumber());
341344
}
342345

343346
@Test // GH-1323

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java

+5
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ private void supportsNullPrecedence() {
7979
assumeThat(database).isNotIn(Database.MySql, Database.MariaDb, Database.SqlServer);
8080
}
8181

82+
private void supportsWhereInTuples() {
83+
assumeThat(database).isIn(Database.MySql, Database.PostgreSql);
84+
}
85+
8286
public void databaseIs(Database database) {
8387
assumeThat(this.database).isEqualTo(database);
8488
}
@@ -112,6 +116,7 @@ public enum Feature {
112116
SUPPORTS_NANOSECOND_PRECISION(TestDatabaseFeatures::supportsNanosecondPrecision), //
113117
SUPPORTS_NULL_PRECEDENCE(TestDatabaseFeatures::supportsNullPrecedence),
114118
IS_POSTGRES(f -> f.databaseIs(Database.PostgreSql)), //
119+
WHERE_IN_TUPLE(TestDatabaseFeatures::supportsWhereInTuples), //
115120
IS_HSQL(f -> f.databaseIs(Database.Hsql));
116121

117122
private final Consumer<TestDatabaseFeatures> featureMethod;

0 commit comments

Comments
 (0)