diff --git a/pom.xml b/pom.xml index ebd3103251..233bd4e77b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 4.0.0-SNAPSHOT + 4.0.0-1935-jdbc-sql-type-for-null-SNAPSHOT pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index b3c39e64c3..79ceae4c47 100644 --- a/spring-data-jdbc-distribution/pom.xml +++ b/spring-data-jdbc-distribution/pom.xml @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 4.0.0-SNAPSHOT + 4.0.0-1935-jdbc-sql-type-for-null-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index e61fd64020..671dfa56c9 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 4.0.0-SNAPSHOT + 4.0.0-1935-jdbc-sql-type-for-null-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 4.0.0-SNAPSHOT + 4.0.0-1935-jdbc-sql-type-for-null-SNAPSHOT diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java index 7460931dab..7dec4f71e5 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java @@ -31,6 +31,7 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.ConverterRegistry; import org.springframework.data.convert.CustomConversions; +import org.springframework.data.jdbc.core.dialect.NullTypeStrategy; import org.springframework.data.jdbc.core.mapping.AggregateReference; import org.springframework.data.jdbc.core.mapping.JdbcValue; import org.springframework.data.jdbc.support.JdbcUtil; @@ -73,6 +74,7 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements private final JdbcTypeFactory typeFactory; private final RelationResolver relationResolver; + private final NullTypeStrategy nullTypeStrategy; /** * Creates a new {@link MappingJdbcConverter} given {@link MappingContext} and a {@link JdbcTypeFactory#unsupported() @@ -84,15 +86,7 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements * @param relationResolver used to fetch additional relations from the database. Must not be {@literal null}. */ public MappingJdbcConverter(RelationalMappingContext context, RelationResolver relationResolver) { - - super(context, new JdbcCustomConversions()); - - Assert.notNull(relationResolver, "RelationResolver must not be null"); - - this.typeFactory = JdbcTypeFactory.unsupported(); - this.relationResolver = relationResolver; - - registerAggregateReferenceConverters(); + this(context, relationResolver, new JdbcCustomConversions(), JdbcTypeFactory.unsupported(), NullTypeStrategy.DEFAULT); } /** @@ -105,13 +99,20 @@ public MappingJdbcConverter(RelationalMappingContext context, RelationResolver r public MappingJdbcConverter(RelationalMappingContext context, RelationResolver relationResolver, CustomConversions conversions, JdbcTypeFactory typeFactory) { + this(context, relationResolver, conversions, typeFactory, NullTypeStrategy.DEFAULT); + } + + public MappingJdbcConverter(RelationalMappingContext context, RelationResolver relationResolver, CustomConversions conversions, JdbcTypeFactory typeFactory, NullTypeStrategy nullTypeStrategy) { + super(context, conversions); Assert.notNull(typeFactory, "JdbcTypeFactory must not be null"); Assert.notNull(relationResolver, "RelationResolver must not be null"); + Assert.notNull(nullTypeStrategy, "NullTypeStrategy must not be null"); this.typeFactory = typeFactory; this.relationResolver = relationResolver; + this.nullTypeStrategy = nullTypeStrategy; registerAggregateReferenceConverters(); } @@ -250,7 +251,11 @@ public JdbcValue writeJdbcValue(@Nullable Object value, TypeInformation colum return result; } - if (convertedValue == null || !convertedValue.getClass().isArray()) { + if (convertedValue == null ) { + return JdbcValue.of(null, nullTypeStrategy.getNullType(sqlType)); + } + + if (!convertedValue.getClass().isArray()) { return JdbcValue.of(convertedValue, sqlType); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlParametersFactory.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlParametersFactory.java index 8bf9bb869f..799216cb05 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlParametersFactory.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlParametersFactory.java @@ -15,6 +15,7 @@ */ package org.springframework.data.jdbc.core.convert; +import java.sql.JDBCType; import java.sql.SQLType; import java.util.ArrayList; import java.util.List; @@ -41,6 +42,7 @@ * @author Jens Schauder * @author Chirag Tailor * @author Mikhail Polivakha + * @author Sergey Korotaev * @since 2.4 */ public class SqlParametersFactory { @@ -187,11 +189,7 @@ private void addConvertedPropertyValue(SqlIdentifierParameterSource parameterSou private void addConvertedValue(SqlIdentifierParameterSource parameterSource, @Nullable Object value, SqlIdentifier paramName, Class javaType, SQLType sqlType) { - JdbcValue jdbcValue = converter.writeJdbcValue( // - value, // - javaType, // - sqlType // - ); + JdbcValue jdbcValue = converter.writeJdbcValue(value, javaType, sqlType); parameterSource.addValue( // paramName, // diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDb2Dialect.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDb2Dialect.java index 2288a44c18..81a326c089 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDb2Dialect.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDb2Dialect.java @@ -66,4 +66,14 @@ public Timestamp convert(OffsetDateTime source) { return Timestamp.from(source.toInstant()); } } + + /** + * DB2 does not support {@link java.sql.JDBCType#NULL}. Therefore it uses {@link NullTypeStrategy#NOOP}. + * + * @since 4.0 + */ + @Override + public NullTypeStrategy getNullTypeStrategy() { + return NullTypeStrategy.NOOP; + } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java index 5728ce4f56..2e5eb6e6c5 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcDialect.java @@ -37,4 +37,15 @@ default JdbcArrayColumns getArraySupport() { return JdbcArrayColumns.Unsupported.INSTANCE; } + /** + * Determines how to handle the {@link java.sql.JDBCType} of {@literal null} values. + * + * The default is suitable for all databases supporting {@link java.sql.JDBCType#NULL}. + * + * @return a strategy to handle the {@link java.sql.JDBCType} of {@literal null} values. Guaranteed not to be null. + * @since 4.0 + */ + default NullTypeStrategy getNullTypeStrategy() { + return NullTypeStrategy.DEFAULT; + } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcSqlServerDialect.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcSqlServerDialect.java index bc45ad3dda..cf59be0a69 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcSqlServerDialect.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/JdbcSqlServerDialect.java @@ -70,4 +70,14 @@ public Instant convert(DateTimeOffset source) { } } + + /** + * SQL Server does not support {@link java.sql.JDBCType#NULL}. Therefore it uses {@link NullTypeStrategy#NOOP}. + * + * @since 4.0 + */ + @Override + public NullTypeStrategy getNullTypeStrategy() { + return NullTypeStrategy.NOOP; + } } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/NullTypeStrategy.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/NullTypeStrategy.java new file mode 100644 index 0000000000..d4a700e656 --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/dialect/NullTypeStrategy.java @@ -0,0 +1,33 @@ +package org.springframework.data.jdbc.core.dialect; + +import java.sql.JDBCType; +import java.sql.SQLType; + +/** + * Interface for defining what to {@link SQLType} to use for {@literal null} values. + * + * @author Jens Schauder + * @since 4.0 + */ +public interface NullTypeStrategy { + + /** + * Implementation that always uses {@link JDBCType#NULL}. Suitable for all databases that actually support this + * {@link JDBCType}. + */ + NullTypeStrategy DEFAULT = sqlType -> JDBCType.NULL; + + /** + * Implementation that uses what ever type was past in as an argument. Suitable for databases that do not support + * {@link JDBCType#NULL}. + */ + NullTypeStrategy NOOP = sqlType -> sqlType; + + /** + * {@link SQLType} to use for {@literal null} values. + * + * @param sqlType a fallback value that is considered suitable by the caller. + * @return Guaranteed not to be {@literal null}. + */ + SQLType getNullType(SQLType sqlType); +} diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java index 8b5f305149..f54a0fc392 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfiguration.java @@ -147,14 +147,12 @@ public IdGeneratingEntityCallback idGeneratingBeforeSaveCallback(JdbcMappingCont */ @Bean public JdbcConverter jdbcConverter(JdbcMappingContext mappingContext, NamedParameterJdbcOperations operations, - @Lazy RelationResolver relationResolver, JdbcCustomConversions conversions, Dialect dialect) { + @Lazy RelationResolver relationResolver, JdbcCustomConversions conversions, JdbcDialect dialect) { - org.springframework.data.jdbc.core.dialect.JdbcArrayColumns arrayColumns = dialect instanceof JdbcDialect jd - ? jd.getArraySupport() - : JdbcArrayColumns.DefaultSupport.INSTANCE; + org.springframework.data.jdbc.core.dialect.JdbcArrayColumns arrayColumns = dialect.getArraySupport(); DefaultJdbcTypeFactory jdbcTypeFactory = new DefaultJdbcTypeFactory(operations.getJdbcOperations(), arrayColumns); - return new MappingJdbcConverter(mappingContext, relationResolver, conversions, jdbcTypeFactory); + return new MappingJdbcConverter(mappingContext, relationResolver, conversions, jdbcTypeFactory, dialect.getNullTypeStrategy()); } /** @@ -222,7 +220,7 @@ public JdbcAggregateTemplate jdbcAggregateTemplate(ApplicationContext applicatio */ @Bean public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations operations, JdbcConverter jdbcConverter, - JdbcMappingContext context, Dialect dialect) { + JdbcMappingContext context, JdbcDialect dialect) { SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, jdbcConverter, dialect); DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, jdbcConverter, operations, @@ -242,7 +240,7 @@ public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations op * cannot be determined. */ @Bean - public Dialect jdbcDialect(NamedParameterJdbcOperations operations) { + public JdbcDialect jdbcDialect(NamedParameterJdbcOperations operations) { return DialectResolver.getDialect(operations.getJdbcOperations()); } diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfiguration.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfiguration.java index 6198fab51e..26afdc6714 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfiguration.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfiguration.java @@ -24,9 +24,9 @@ import org.springframework.data.jdbc.core.convert.DataAccessStrategy; import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.QueryMappingConfiguration; +import org.springframework.data.jdbc.core.dialect.JdbcDialect; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.mybatis.MyBatisDataAccessStrategy; -import org.springframework.data.relational.core.dialect.Dialect; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; /** @@ -46,7 +46,7 @@ public class MyBatisJdbcConfiguration extends AbstractJdbcConfiguration { @Bean @Override public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations operations, JdbcConverter jdbcConverter, - JdbcMappingContext context, Dialect dialect) { + JdbcMappingContext context, JdbcDialect dialect) { return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, jdbcConverter, operations, session, dialect, queryMappingConfiguration.orElse(QueryMappingConfiguration.EMPTY)); diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlParametersFactoryTest.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlParametersFactoryUnitTests.java similarity index 73% rename from spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlParametersFactoryTest.java rename to spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlParametersFactoryUnitTests.java index 9efdb3aeab..4184c52217 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlParametersFactoryTest.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/SqlParametersFactoryUnitTests.java @@ -21,6 +21,8 @@ import static org.mockito.Mockito.*; import static org.springframework.data.jdbc.core.convert.DefaultDataAccessStrategyUnitTests.*; +import java.sql.JDBCType; +import java.sql.Types; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -32,6 +34,7 @@ import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; +import org.springframework.data.jdbc.core.mapping.JdbcValue; import org.springframework.data.relational.core.conversion.IdValueSource; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.RelationalMappingContext; @@ -42,8 +45,9 @@ * Unit tests for {@link SqlParametersFactory}. * * @author Chirag Tailor + * @author Sergey Korotaev */ -class SqlParametersFactoryTest { +class SqlParametersFactoryUnitTests { RelationalMappingContext context = new JdbcMappingContext(); RelationResolver relationResolver = mock(RelationResolver.class); @@ -85,8 +89,7 @@ public void considersConfiguredWriteConverterForIdValueObjectsWhichReferencedInO assertThat(sqlParameterSource.getValue("DUMMYENTITYROOT")).isEqualTo(rawId); } - @Test - // DATAJDBC-146 + @Test // DATAJDBC-146 void identifiersGetAddedAsParameters() { long id = 4711L; @@ -100,8 +103,7 @@ void identifiersGetAddedAsParameters() { assertThat(sqlParameterSource.getValue("reference")).isEqualTo(reference); } - @Test - // DATAJDBC-146 + @Test // DATAJDBC-146 void additionalIdentifierForIdDoesNotLeadToDuplicateParameters() { long id = 4711L; @@ -113,8 +115,7 @@ void additionalIdentifierForIdDoesNotLeadToDuplicateParameters() { assertThat(sqlParameterSource.getValue("id")).isEqualTo(id); } - @Test - // DATAJDBC-235 + @Test // DATAJDBC-235 void considersConfiguredWriteConverter() { SqlParametersFactory sqlParametersFactory = createSqlParametersFactoryWithConverters( @@ -128,8 +129,7 @@ void considersConfiguredWriteConverter() { assertThat(sqlParameterSource.getValue("flag")).isEqualTo("T"); } - @Test - // DATAJDBC-412 + @Test // DATAJDBC-412 void considersConfiguredWriteConverterForIdValueObjects_onWrite() { SqlParametersFactory sqlParametersFactory = createSqlParametersFactoryWithConverters( @@ -146,8 +146,7 @@ void considersConfiguredWriteConverterForIdValueObjects_onWrite() { assertThat(sqlParameterSource.getValue("value")).isEqualTo(value); } - @Test - // GH-1405 + @Test // GH-1405 void parameterNamesGetSanitized() { WithIllegalCharacters entity = new WithIllegalCharacters(23L, "aValue"); @@ -162,6 +161,65 @@ void parameterNamesGetSanitized() { assertThat(sqlParameterSource.getValue("val&ue")).isNull(); } + @Test // GH-1935 + void enumParameterIsNotNullReturnCorrectSqlTypeFromConverter() { + + WithEnumEntity entity = new WithEnumEntity(23L, DummyEnum.ONE); + + SqlParametersFactory sqlParametersFactory = createSqlParametersFactoryWithConverters( + singletonList(WritingEnumConverter.INSTANCE)); + + SqlIdentifierParameterSource sqlParameterSource = sqlParametersFactory.forInsert(entity, WithEnumEntity.class, + Identifier.empty(), IdValueSource.PROVIDED); + + assertThat(sqlParameterSource.getValue("id")).isEqualTo(23L); + assertThat(sqlParameterSource.getValue("dummy_enum")).isEqualTo(DummyEnum.ONE.name()); + assertThat(sqlParameterSource.getSqlType("dummy_enum")).isEqualTo(Types.OTHER); + } + + @Test // GH-1935 + void enumParameterIsNullReturnCorrectSqlTypeFromConverter() { + WithEnumEntity entity = new WithEnumEntity(23L, null); + + SqlParametersFactory sqlParametersFactory = createSqlParametersFactoryWithConverters( + singletonList(WritingEnumConverter.INSTANCE)); + + SqlIdentifierParameterSource sqlParameterSource = sqlParametersFactory.forInsert(entity, WithEnumEntity.class, + Identifier.empty(), IdValueSource.PROVIDED); + + assertThat(sqlParameterSource.getValue("id")).isEqualTo(23L); + assertThat(sqlParameterSource.getValue("dummy_enum")).isNull(); + assertThat(sqlParameterSource.getSqlType("dummy_enum")).isEqualTo(Types.NULL); + } + + @Test // GH-1935 + void enumParameterIsNotNullReturnCorrectSqlTypeWithoutConverter() { + + WithEnumEntity entity = new WithEnumEntity(23L, DummyEnum.ONE); + + SqlIdentifierParameterSource sqlParameterSource = sqlParametersFactory.forInsert(entity, WithEnumEntity.class, + Identifier.empty(), IdValueSource.PROVIDED); + + assertThat(sqlParameterSource.getValue("id")).isEqualTo(23L); + assertThat(sqlParameterSource.getValue("dummy_enum")).isEqualTo(DummyEnum.ONE.name()); + assertThat(sqlParameterSource.getSqlType("dummy_enum")).isEqualTo(Types.VARCHAR); + + } + + @Test // GH-1935 + void enumParameterIsNullReturnCorrectSqlTypeWithoutConverter() { + + WithEnumEntity entity = new WithEnumEntity(23L, null); + + SqlIdentifierParameterSource sqlParameterSource = sqlParametersFactory.forInsert(entity, WithEnumEntity.class, + Identifier.empty(), IdValueSource.PROVIDED); + + assertThat(sqlParameterSource.getValue("id")).isEqualTo(23L); + assertThat(sqlParameterSource.getSqlType("dummy_enum")).isEqualTo(JDBCType.NULL.getVendorTypeNumber()); + assertThat(sqlParameterSource.getValue("dummy_enum")).isNull(); + + } + @WritingConverter enum IdValueToStringConverter implements Converter { @@ -225,7 +283,18 @@ public int hashCode() { } public String toString() { - return "SqlParametersFactoryTest.IdValue(id=" + this.getId() + ")"; + return "SqlParametersFactoryUnitTests.IdValue(id=" + this.getId() + ")"; + } + } + + @WritingConverter + enum WritingEnumConverter implements Converter { + + INSTANCE; + + @Override + public JdbcValue convert(DummyEnum source) { + return JdbcValue.of(source.name().toUpperCase(), JDBCType.OTHER); } } @@ -295,6 +364,21 @@ public WithIllegalCharacters(Long id, String value) { } } + private static class WithEnumEntity { + @Id Long id; + + DummyEnum dummyEnum; + + public WithEnumEntity(Long id, DummyEnum dummyEnum) { + this.id = id; + this.dummyEnum = dummyEnum; + } + } + + private enum DummyEnum { + ONE, TWO + } + private SqlParametersFactory createSqlParametersFactoryWithConverters(List converters) { MappingJdbcConverter converter = new MappingJdbcConverter(context, relationResolver, diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfigurationIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfigurationIntegrationTests.java index 9c8ee97388..1e9b22ba38 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfigurationIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/AbstractJdbcConfigurationIntegrationTests.java @@ -36,6 +36,7 @@ import org.springframework.data.jdbc.core.convert.DataAccessStrategy; import org.springframework.data.jdbc.core.convert.JdbcConverter; import org.springframework.data.jdbc.core.convert.JdbcCustomConversions; +import org.springframework.data.jdbc.core.dialect.JdbcDialect; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.relational.RelationalManagedTypes; import org.springframework.data.relational.core.dialect.Dialect; @@ -142,7 +143,7 @@ static class AbstractJdbcConfigurationUnderTest extends AbstractJdbcConfiguratio @Override @Bean - public Dialect jdbcDialect(NamedParameterJdbcOperations operations) { + public JdbcDialect jdbcDialect(NamedParameterJdbcOperations operations) { return new DummyDialect(); } @@ -165,7 +166,7 @@ private static class Blah {} private static class Blubb {} - private static class DummyDialect implements Dialect { + private static class DummyDialect implements JdbcDialect { @Override public LimitClause limit() { return null; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfigurationIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfigurationIntegrationTests.java index b0ad7a4b1a..adab02fe43 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfigurationIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/config/MyBatisJdbcConfigurationIntegrationTests.java @@ -26,6 +26,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.data.jdbc.core.convert.CascadingDataAccessStrategy; import org.springframework.data.jdbc.core.convert.DataAccessStrategy; +import org.springframework.data.jdbc.core.dialect.JdbcDialect; import org.springframework.data.jdbc.core.dialect.JdbcHsqlDbDialect; import org.springframework.data.jdbc.mybatis.MyBatisDataAccessStrategy; import org.springframework.data.relational.core.dialect.Dialect; @@ -70,7 +71,7 @@ public static class MyBatisJdbcConfigurationUnderTest extends MyBatisJdbcConfigu @Override @Bean - public Dialect jdbcDialect(NamedParameterJdbcOperations operations) { + public JdbcDialect jdbcDialect(NamedParameterJdbcOperations operations) { return JdbcHsqlDbDialect.INSTANCE; } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java index 4ea56b1ee7..f09fbd0b71 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java @@ -22,9 +22,7 @@ import javax.sql.DataSource; -import org.apache.ibatis.session.SqlSessionFactory; import org.mockito.Mockito; -import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationEventPublisher; @@ -36,7 +34,6 @@ import org.springframework.context.annotation.Profile; import org.springframework.data.convert.CustomConversions; import org.springframework.data.jdbc.core.convert.*; -import org.springframework.data.jdbc.core.dialect.JdbcArrayColumns; import org.springframework.data.jdbc.core.dialect.JdbcDialect; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes; @@ -78,9 +75,7 @@ public class TestConfiguration { public static final String PROFILE_NO_SINGLE_QUERY_LOADING = "!" + PROFILE_SINGLE_QUERY_LOADING; @Autowired DataSource dataSource; - @Autowired BeanFactory beanFactory; @Autowired ApplicationEventPublisher publisher; - @Autowired(required = false) SqlSessionFactory sqlSessionFactory; @Bean JdbcRepositoryFactory jdbcRepositoryFactory( @@ -162,17 +157,15 @@ private List storeConverters(Dialect dialect) { @Bean JdbcConverter relationalConverter(RelationalMappingContext mappingContext, @Lazy RelationResolver relationResolver, CustomConversions conversions, @Qualifier("namedParameterJdbcTemplate") NamedParameterJdbcOperations template, - Dialect dialect) { + JdbcDialect dialect) { - org.springframework.data.jdbc.core.dialect.JdbcArrayColumns arrayColumns = dialect instanceof JdbcDialect - ? ((JdbcDialect) dialect).getArraySupport() - : JdbcArrayColumns.DefaultSupport.INSTANCE; + org.springframework.data.jdbc.core.dialect.JdbcArrayColumns arrayColumns = dialect.getArraySupport(); return new MappingJdbcConverter( // mappingContext, // relationResolver, // conversions, // - new DefaultJdbcTypeFactory(template.getJdbcOperations(), arrayColumns)); + new DefaultJdbcTypeFactory(template.getJdbcOperations(), arrayColumns), dialect.getNullTypeStrategy()); } /** @@ -188,7 +181,7 @@ public IdGeneratingEntityCallback idGeneratingBeforeSaveCallback(JdbcMappingCont } @Bean - Dialect jdbcDialect(NamedParameterJdbcOperations operations) { + JdbcDialect jdbcDialect(NamedParameterJdbcOperations operations) { return DialectResolver.getDialect(operations.getJdbcOperations()); } diff --git a/spring-data-r2dbc/pom.xml b/spring-data-r2dbc/pom.xml index 3ee76fd3c1..e85f4760f9 100644 --- a/spring-data-r2dbc/pom.xml +++ b/spring-data-r2dbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-r2dbc - 4.0.0-SNAPSHOT + 4.0.0-1935-jdbc-sql-type-for-null-SNAPSHOT Spring Data R2DBC Spring Data module for R2DBC @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 4.0.0-SNAPSHOT + 4.0.0-1935-jdbc-sql-type-for-null-SNAPSHOT diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 8fd6d7a6f0..7eacd71180 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 4.0.0-SNAPSHOT + 4.0.0-1935-jdbc-sql-type-for-null-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 4.0.0-SNAPSHOT + 4.0.0-1935-jdbc-sql-type-for-null-SNAPSHOT