Browse Source

Polishing.

Correctly assign SQL type for tuples.

See #1323
Original pull request: #1838
3.3.x
Mark Paluch 1 year ago
parent
commit
94fcdc5cd4
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 21
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java
  2. 9
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/support/JdbcUtil.java
  3. 18
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java
  4. 3
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java
  5. 5
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestDatabaseFeatures.java

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

@ -19,7 +19,6 @@ import static org.springframework.data.jdbc.repository.query.JdbcQueryExecution. @@ -19,7 +19,6 @@ import static org.springframework.data.jdbc.repository.query.JdbcQueryExecution.
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.sql.JDBCType;
import java.sql.SQLType;
import java.util.ArrayList;
import java.util.Collection;
@ -31,8 +30,10 @@ import java.util.function.Supplier; @@ -31,8 +30,10 @@ import java.util.function.Supplier;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.data.jdbc.core.convert.JdbcColumnTypes;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.mapping.JdbcValue;
import org.springframework.data.jdbc.support.JdbcUtil;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.repository.query.RelationalParameterAccessor;
import org.springframework.data.relational.repository.query.RelationalParametersParameterAccessor;
@ -223,7 +224,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -223,7 +224,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
if (actualType != null && actualType.getType().isArray()) {
TypeInformation<?> nestedElementType = actualType.getRequiredActualType();
return writeCollection(collection, JDBCType.OTHER,
return writeCollection(collection, parameter.getActualSqlType(),
array -> writeArrayValue(parameter, array, nestedElementType));
}
@ -265,21 +266,29 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -265,21 +266,29 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
return jdbcValue;
}
private Object[] writeArrayValue(JdbcParameters.JdbcParameter parameter, Object array,
private JdbcValue writeArrayValue(JdbcParameters.JdbcParameter parameter, Object array,
TypeInformation<?> nestedElementType) {
int length = Array.getLength(array);
Object[] mappedArray = new Object[length];
SQLType sqlType = null;
for (int i = 0; i < length; i++) {
Object element = Array.get(array, i);
JdbcValue elementJdbcValue = converter.writeJdbcValue(element, nestedElementType, parameter.getActualSqlType());
JdbcValue converted = converter.writeJdbcValue(element, nestedElementType, parameter.getActualSqlType());
mappedArray[i] = elementJdbcValue.getValue();
if (sqlType == null && converted.getJdbcType() != null) {
sqlType = converted.getJdbcType();
}
mappedArray[i] = converted.getValue();
}
if (sqlType == null) {
sqlType = JdbcUtil.targetSqlTypeFor(JdbcColumnTypes.INSTANCE.resolvePrimitiveType(nestedElementType.getType()));
}
return mappedArray;
return JdbcValue.of(mappedArray, sqlType);
}
RowMapper<Object> determineRowMapper(ResultProcessor resultProcessor, boolean hasDynamicProjection) {

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

@ -22,13 +22,11 @@ import java.sql.JDBCType; @@ -22,13 +22,11 @@ import java.sql.JDBCType;
import java.sql.SQLType;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@ -54,7 +52,12 @@ public final class JdbcUtil { @@ -54,7 +52,12 @@ public final class JdbcUtil {
public Integer getVendorTypeNumber() {
return JdbcUtils.TYPE_UNKNOWN;
}
} ;
@Override
public String toString() {
return getName();
}
};
private static final Map<Class<?>, SQLType> sqlTypeMappings = new HashMap<>();
static {

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

@ -41,6 +41,7 @@ import org.junit.jupiter.api.Test; @@ -41,6 +41,7 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.ApplicationListener;
@ -66,6 +67,7 @@ import org.springframework.data.jdbc.repository.query.Query; @@ -66,6 +67,7 @@ import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.jdbc.testing.ConditionalOnDatabase;
import org.springframework.data.jdbc.testing.DatabaseType;
import org.springframework.data.jdbc.testing.EnabledOnDatabase;
import org.springframework.data.jdbc.testing.EnabledOnFeature;
import org.springframework.data.jdbc.testing.IntegrationTest;
import org.springframework.data.jdbc.testing.TestConfiguration;
@ -107,6 +109,7 @@ import org.springframework.test.jdbc.JdbcTestUtils; @@ -107,6 +109,7 @@ import org.springframework.test.jdbc.JdbcTestUtils;
* @author Paul Jones
*/
@IntegrationTest
@EnabledOnDatabase(DatabaseType.MARIADB)
public class JdbcRepositoryIntegrationTests {
@Autowired NamedParameterJdbcTemplate template;
@ -1339,15 +1342,15 @@ public class JdbcRepositoryIntegrationTests { @@ -1339,15 +1342,15 @@ public class JdbcRepositoryIntegrationTests {
}
@Test // GH-1323
@EnabledOnFeature(TestDatabaseFeatures.Feature.WHERE_IN_TUPLE)
void queryWithTupleIn() {
DummyEntity one = repository.save(createDummyEntity("one"));
DummyEntity two = repository.save(createDummyEntity( "two"));
DummyEntity three = repository.save(createDummyEntity( "three"));
DummyEntity two = repository.save(createDummyEntity("two"));
DummyEntity three = repository.save(createDummyEntity("three"));
List<Object[]> tuples = List.of(
new Object[]{two.idProp, "two"}, // matches "two"
new Object[]{three.idProp, "two"} // matches nothing
List<Object[]> tuples = List.of(new Object[] { two.idProp, "two" }, // matches "two"
new Object[] { three.idProp, "two" } // matches nothing
);
List<DummyEntity> result = repository.findByListInTuple(tuples);
@ -1887,6 +1890,11 @@ public class JdbcRepositoryIntegrationTests { @@ -1887,6 +1890,11 @@ public class JdbcRepositoryIntegrationTests {
public int hashCode() {
return Objects.hash(name, pointInTime, offsetDateTime, idProp, flag, ref, direction);
}
@Override
public String toString() {
return "DummyEntity{" + "name='" + name + '\'' + ", idProp=" + idProp + '}';
}
}
enum Direction {

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

@ -49,6 +49,7 @@ import org.springframework.data.jdbc.core.convert.JdbcTypeFactory; @@ -49,6 +49,7 @@ import org.springframework.data.jdbc.core.convert.JdbcTypeFactory;
import org.springframework.data.jdbc.core.convert.MappingJdbcConverter;
import org.springframework.data.jdbc.core.convert.RelationResolver;
import org.springframework.data.jdbc.core.mapping.JdbcValue;
import org.springframework.data.jdbc.support.JdbcUtil;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.repository.Repository;
@ -338,6 +339,8 @@ class StringBasedJdbcQueryUnitTests { @@ -338,6 +339,8 @@ class StringBasedJdbcQueryUnitTests {
assertThat(parameterSource.getValue("tuples"))
.asInstanceOf(LIST)
.containsExactly(tuples);
assertThat(parameterSource.getSqlType("tuples")).isEqualTo(JdbcUtil.TYPE_UNKNOWN.getVendorTypeNumber());
}
@Test // GH-1323

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

@ -79,6 +79,10 @@ public class TestDatabaseFeatures { @@ -79,6 +79,10 @@ public class TestDatabaseFeatures {
assumeThat(database).isNotIn(Database.MySql, Database.MariaDb, Database.SqlServer);
}
private void supportsWhereInTuples() {
assumeThat(database).isIn(Database.MySql, Database.PostgreSql);
}
public void databaseIs(Database database) {
assumeThat(this.database).isEqualTo(database);
}
@ -112,6 +116,7 @@ public class TestDatabaseFeatures { @@ -112,6 +116,7 @@ public class TestDatabaseFeatures {
SUPPORTS_NANOSECOND_PRECISION(TestDatabaseFeatures::supportsNanosecondPrecision), //
SUPPORTS_NULL_PRECEDENCE(TestDatabaseFeatures::supportsNullPrecedence),
IS_POSTGRES(f -> f.databaseIs(Database.PostgreSql)), //
WHERE_IN_TUPLE(TestDatabaseFeatures::supportsWhereInTuples), //
IS_HSQL(f -> f.databaseIs(Database.Hsql));
private final Consumer<TestDatabaseFeatures> featureMethod;

Loading…
Cancel
Save