From e15dbd97bc9c226897470e656a8644888147c147 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Tue, 24 Jan 2023 15:04:25 +0100 Subject: [PATCH 1/3] prepare branch issue/1406-delimited-identifiers --- pom.xml | 2 +- spring-data-jdbc-distribution/pom.xml | 2 +- spring-data-jdbc/pom.xml | 4 ++-- spring-data-r2dbc/pom.xml | 4 ++-- spring-data-relational/pom.xml | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 530667df21..af6361dce1 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-relational-parent - 3.1.0-SNAPSHOT + 3.1.0-1406-delimited-identifiers-SNAPSHOT pom Spring Data Relational Parent diff --git a/spring-data-jdbc-distribution/pom.xml b/spring-data-jdbc-distribution/pom.xml index 6e018ca17d..2be30f40df 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 - 3.1.0-SNAPSHOT + 3.1.0-1406-delimited-identifiers-SNAPSHOT ../pom.xml diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index aa6936d760..5895fc0aab 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-jdbc - 3.1.0-SNAPSHOT + 3.1.0-1406-delimited-identifiers-SNAPSHOT Spring Data JDBC Spring Data module for JDBC repositories. @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 3.1.0-SNAPSHOT + 3.1.0-1406-delimited-identifiers-SNAPSHOT diff --git a/spring-data-r2dbc/pom.xml b/spring-data-r2dbc/pom.xml index ef55d4bd1b..5f0d1dd057 100644 --- a/spring-data-r2dbc/pom.xml +++ b/spring-data-r2dbc/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-r2dbc - 3.1.0-SNAPSHOT + 3.1.0-1406-delimited-identifiers-SNAPSHOT Spring Data R2DBC Spring Data module for R2DBC @@ -15,7 +15,7 @@ org.springframework.data spring-data-relational-parent - 3.1.0-SNAPSHOT + 3.1.0-1406-delimited-identifiers-SNAPSHOT diff --git a/spring-data-relational/pom.xml b/spring-data-relational/pom.xml index 71d009990b..a114071937 100644 --- a/spring-data-relational/pom.xml +++ b/spring-data-relational/pom.xml @@ -6,7 +6,7 @@ 4.0.0 spring-data-relational - 3.1.0-SNAPSHOT + 3.1.0-1406-delimited-identifiers-SNAPSHOT Spring Data Relational Spring Data Relational support @@ -14,7 +14,7 @@ org.springframework.data spring-data-relational-parent - 3.1.0-SNAPSHOT + 3.1.0-1406-delimited-identifiers-SNAPSHOT From 5e892bcc9810cf165f1f0321c9190c52040696d7 Mon Sep 17 00:00:00 2001 From: Mikhail2048 Date: Mon, 9 Jan 2023 11:34:25 +0300 Subject: [PATCH 2/3] Integration test added to demonstrate behaviour when column names contain characters illegal for bind parameters. See #1405 Original pull request #1406 --- .../JdbcRepositoryIntegrationTests.java | 42 +++++++++++++++++-- .../JdbcRepositoryIntegrationTests-db2.sql | 8 ++++ .../JdbcRepositoryIntegrationTests-h2.sql | 7 ++++ .../JdbcRepositoryIntegrationTests-hsql.sql | 7 ++++ ...JdbcRepositoryIntegrationTests-mariadb.sql | 7 ++++ .../JdbcRepositoryIntegrationTests-mssql.sql | 8 ++++ .../JdbcRepositoryIntegrationTests-mysql.sql | 6 +++ .../JdbcRepositoryIntegrationTests-oracle.sql | 8 ++++ ...dbcRepositoryIntegrationTests-postgres.sql | 8 ++++ 9 files changed, 97 insertions(+), 4 deletions(-) diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index b632a6ba70..9c9c8646ff 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -69,7 +69,9 @@ import org.springframework.data.jdbc.testing.EnabledOnFeature; import org.springframework.data.jdbc.testing.TestConfiguration; import org.springframework.data.jdbc.testing.TestDatabaseFeatures; +import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.MappedCollection; +import org.springframework.data.relational.core.mapping.Table; import org.springframework.data.relational.core.mapping.event.AbstractRelationalEvent; import org.springframework.data.relational.core.mapping.event.AfterConvertEvent; import org.springframework.data.relational.core.sql.LockMode; @@ -113,6 +115,8 @@ public class JdbcRepositoryIntegrationTests { @Autowired MyEventListener eventListener; @Autowired RootRepository rootRepository; + @Autowired WithDelimitedColumnRepository withDelimitedColumnRepository; + private static DummyEntity createDummyEntity() { DummyEntity entity = new DummyEntity(); @@ -1238,6 +1242,22 @@ void fetchByExampleFluentOnlyInstantOneValueAsSimple() { assertThat(match.get().getName()).contains(two.getName()); } + @Test + void withDelimitedColumnTest() { + WithDelimitedColumn withDelimitedColumn = new WithDelimitedColumn(); + withDelimitedColumn.setType("TYPICAL"); + withDelimitedColumn.setIdentifier("UR-123"); + + WithDelimitedColumn saved = withDelimitedColumnRepository.save(withDelimitedColumn); + + assertThat(saved.getId()).isNotNull(); + + Optional inDatabase = withDelimitedColumnRepository.findById(saved.getId()); + + assertThat(inDatabase).isPresent(); + assertThat(inDatabase.get().getIdentifier()).isEqualTo("UR-123"); + } + private Root createRoot(String namePrefix) { return new Root(null, namePrefix, @@ -1361,10 +1381,17 @@ interface DummyEntityRepository extends CrudRepository, Query List findByEnumType(Direction direction); } + interface RootRepository extends ListCrudRepository { + List findAllByOrderByIdAsc(); + } + + interface WithDelimitedColumnRepository extends CrudRepository { } + @Configuration @Import(TestConfiguration.class) static class Config { + @Autowired JdbcRepositoryFactory factory; @Bean @@ -1382,6 +1409,9 @@ RootRepository rootRepository() { return factory.getRepository(RootRepository.class); } + @Bean + WithDelimitedColumnRepository withDelimitedColumnRepository() { return factory.getRepository(WithDelimitedColumnRepository.class); } + @Bean NamedQueries namedQueries() throws IOException { @@ -1404,15 +1434,11 @@ public ExtensionAwareQueryMethodEvaluationContextProvider extensionAware(List { - List findAllByOrderByIdAsc(); } @Value @@ -1424,6 +1450,14 @@ static class Root { @MappedCollection(idColumn = "ROOT_ID", keyColumn = "ROOT_KEY") List intermediates; } + @Data + @Table("WITH_DELIMITED_COLUMN") + static class WithDelimitedColumn { + @Id Long id; + @Column("ORG.XTUNIT.IDENTIFIER") String identifier; + @Column ("STYPE") String type; + } + @Value static class Intermediate { diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-db2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-db2.sql index 4916d64b02..e75d0a61bc 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-db2.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-db2.sql @@ -2,6 +2,7 @@ DROP TABLE dummy_entity; DROP TABLE ROOT; DROP TABLE INTERMEDIATE; DROP TABLE LEAF; +DROP TABLE WITH_DELIMITED_COLUMN; CREATE TABLE dummy_entity ( @@ -37,3 +38,10 @@ CREATE TABLE LEAF INTERMEDIATE_ID BIGINT, INTERMEDIATE_KEY INTEGER ); + +CREATE TABLE WITH_DELIMITED_COLUMN +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, + "ORG.XTUNIT.IDENTIFIER" VARCHAR(100), + STYPE VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-h2.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-h2.sql index c9eedd6b51..724cd2ba00 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-h2.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-h2.sql @@ -32,3 +32,10 @@ CREATE TABLE LEAF INTERMEDIATE_ID BIGINT, INTERMEDIATE_KEY INTEGER ); + +CREATE TABLE WITH_DELIMITED_COLUMN +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, + "ORG.XTUNIT.IDENTIFIER" VARCHAR(100), + STYPE VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql index c9eedd6b51..724cd2ba00 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-hsql.sql @@ -32,3 +32,10 @@ CREATE TABLE LEAF INTERMEDIATE_ID BIGINT, INTERMEDIATE_KEY INTEGER ); + +CREATE TABLE WITH_DELIMITED_COLUMN +( + ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY, + "ORG.XTUNIT.IDENTIFIER" VARCHAR(100), + STYPE VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mariadb.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mariadb.sql index 5a4a83d6e2..7617b01bf2 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mariadb.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mariadb.sql @@ -32,3 +32,10 @@ CREATE TABLE LEAF INTERMEDIATE_ID BIGINT, INTERMEDIATE_KEY INTEGER ); + +CREATE TABLE WITH_DELIMITED_COLUMN +( + ID BIGINT AUTO_INCREMENT PRIMARY KEY, + `ORG.XTUNIT.IDENTIFIER` VARCHAR(100), + STYPE VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mssql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mssql.sql index 458bbd0b57..cabaa038b8 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mssql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mssql.sql @@ -2,6 +2,7 @@ DROP TABLE IF EXISTS dummy_entity; DROP TABLE IF EXISTS ROOT; DROP TABLE IF EXISTS INTERMEDIATE; DROP TABLE IF EXISTS LEAF; +DROP TABLE IF EXISTS WITH_DELIMITED_COLUMN; CREATE TABLE dummy_entity ( @@ -37,3 +38,10 @@ CREATE TABLE LEAF INTERMEDIATE_ID BIGINT, INTERMEDIATE_KEY INTEGER ); + +CREATE TABLE WITH_DELIMITED_COLUMN +( + ID BIGINT IDENTITY PRIMARY KEY, + "ORG.XTUNIT.IDENTIFIER" VARCHAR(100), + STYPE VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql index 0999586459..00175585d7 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-mysql.sql @@ -36,3 +36,9 @@ CREATE TABLE LEAF INTERMEDIATE_KEY INTEGER ); +CREATE TABLE WITH_DELIMITED_COLUMN +( + ID BIGINT AUTO_INCREMENT PRIMARY KEY, + `ORG.XTUNIT.IDENTIFIER` VARCHAR(100), + STYPE VARCHAR(100) +); \ No newline at end of file diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-oracle.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-oracle.sql index 518e667c1a..6383e3c624 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-oracle.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-oracle.sql @@ -2,6 +2,7 @@ DROP TABLE DUMMY_ENTITY CASCADE CONSTRAINTS PURGE; DROP TABLE ROOT CASCADE CONSTRAINTS PURGE; DROP TABLE INTERMEDIATE CASCADE CONSTRAINTS PURGE; DROP TABLE LEAF CASCADE CONSTRAINTS PURGE; +DROP TABLE WITH_DELIMITED_COLUMN CASCADE CONSTRAINTS PURGE; CREATE TABLE DUMMY_ENTITY ( @@ -37,3 +38,10 @@ CREATE TABLE LEAF INTERMEDIATE_ID NUMBER, INTERMEDIATE_KEY NUMBER ); + +CREATE TABLE WITH_DELIMITED_COLUMN +( + ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY, + "ORG.XTUNIT.IDENTIFIER" VARCHAR(100), + STYPE VARCHAR(100) +) diff --git a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql index 8bcd1735ee..a757002cac 100644 --- a/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql +++ b/spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryIntegrationTests-postgres.sql @@ -2,6 +2,7 @@ DROP TABLE dummy_entity; DROP TABLE ROOT; DROP TABLE INTERMEDIATE; DROP TABLE LEAF; +DROP TABLE WITH_DELIMITED_COLUMN; CREATE TABLE dummy_entity ( @@ -37,3 +38,10 @@ CREATE TABLE LEAF "INTERMEDIATE_ID" BIGINT, "INTERMEDIATE_KEY" INTEGER ); + +CREATE TABLE "WITH_DELIMITED_COLUMN" +( + ID BIGINT IDENTITY PRIMARY KEY, + "ORG.XTUNIT.IDENTIFIER" VARCHAR(100), + STYPE VARCHAR(100) +); \ No newline at end of file From 528db605472edbd3d8e9a14feff0388ced62b09e Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Mon, 23 Jan 2023 15:49:28 +0100 Subject: [PATCH 3/3] SqlIdentifierParameterSource now sanitizes identifier names. Closes #1405 See #1406 --- .../convert/BindParameterNameSanitizer.java | 37 +++++++++++++++++++ .../data/jdbc/core/convert/SqlGenerator.java | 3 +- .../convert/SqlIdentifierParameterSource.java | 2 +- .../core/convert/SqlParametersFactory.java | 4 +- .../convert/SqlParametersFactoryTest.java | 26 +++++++++++++ .../JdbcRepositoryIntegrationTests.java | 4 +- 6 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BindParameterNameSanitizer.java diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BindParameterNameSanitizer.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BindParameterNameSanitizer.java new file mode 100644 index 0000000000..c84658c48c --- /dev/null +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BindParameterNameSanitizer.java @@ -0,0 +1,37 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.data.jdbc.core.convert; + +import java.util.regex.Pattern; + +/** + * Sanitizes the name of bind parameters, so they don't contain any illegal characters. + * + * @author Jens Schauder + * + * @since 3.0 + */ +enum BindParameterNameSanitizer { + INSTANCE; + + private static final Pattern parameterPattern = Pattern.compile("\\W"); + + String sanitize(String rawName) { + + return parameterPattern.matcher(rawName).replaceAll(""); + } +} diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java index 0afebf1c6e..731881b9e4 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlGenerator.java @@ -66,7 +66,6 @@ class SqlGenerator { static final SqlIdentifier IDS_SQL_PARAMETER = SqlIdentifier.unquoted("ids"); static final SqlIdentifier ROOT_ID_PARAMETER = SqlIdentifier.unquoted("rootId"); - private static final Pattern parameterPattern = Pattern.compile("\\W"); private final RelationalPersistentEntity entity; private final MappingContext, RelationalPersistentProperty> mappingContext; private final RenderContext renderContext; @@ -159,7 +158,7 @@ private Condition getSubselectCondition(PersistentPropertyPathExtension path, } private BindMarker getBindMarker(SqlIdentifier columnName) { - return SQL.bindMarker(":" + parameterPattern.matcher(renderReference(columnName)).replaceAll("")); + return SQL.bindMarker(":" + BindParameterNameSanitizer.INSTANCE.sanitize(renderReference(columnName))); } /** diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlIdentifierParameterSource.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlIdentifierParameterSource.java index fc89db7676..4398e877c9 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlIdentifierParameterSource.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/SqlIdentifierParameterSource.java @@ -68,7 +68,7 @@ void addValue(SqlIdentifier name, Object value) { void addValue(SqlIdentifier identifier, Object value, int sqlType) { identifiers.add(identifier); - String name = identifier.getReference(identifierProcessing); + String name = BindParameterNameSanitizer.INSTANCE.sanitize(identifier.getReference(identifierProcessing)); namesToValues.put(name, value); registerSqlType(name, 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 103b92b237..d87e607fa0 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 @@ -95,8 +95,8 @@ SqlIdentifierParameterSource forInsert(T instance, Class domainType, Iden */ SqlIdentifierParameterSource forUpdate(T instance, Class domainType) { - return getParameterSource(instance, getRequiredPersistentEntity(domainType), "", RelationalPersistentProperty::isInsertOnly, - dialect.getIdentifierProcessing()); + return getParameterSource(instance, getRequiredPersistentEntity(domainType), "", + RelationalPersistentProperty::isInsertOnly, dialect.getIdentifierProcessing()); } /** 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/SqlParametersFactoryTest.java index 292b822c81..25d37ca997 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/SqlParametersFactoryTest.java @@ -38,6 +38,7 @@ import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.relational.core.conversion.IdValueSource; import org.springframework.data.relational.core.dialect.AnsiDialect; +import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.sql.SqlIdentifier; import org.springframework.jdbc.core.JdbcOperations; @@ -147,6 +148,21 @@ void considersConfiguredWriteConverterForIdValueObjects_onWrite() { assertThat(sqlParameterSource.getValue("value")).isEqualTo(value); } + @Test // GH-1405 + void parameterNamesGetSanitized() { + + WithIllegalCharacters entity = new WithIllegalCharacters(23L,"aValue"); + + SqlIdentifierParameterSource sqlParameterSource = sqlParametersFactory.forInsert(entity, WithIllegalCharacters.class, + Identifier.empty(), IdValueSource.PROVIDED); + + assertThat(sqlParameterSource.getValue("id")).isEqualTo(23L); + assertThat(sqlParameterSource.getValue("value")).isEqualTo("aValue"); + + assertThat(sqlParameterSource.getValue("i.d")).isNull(); + assertThat(sqlParameterSource.getValue("val&ue")).isNull(); + } + @WritingConverter enum IdValueToStringConverter implements Converter { @@ -212,6 +228,16 @@ private static class DummyEntity { @Id private final Long id; } + @AllArgsConstructor + private static class WithIllegalCharacters { + + @Column("i.d") + @Id Long id; + + @Column("val&ue") + String value; + } + private SqlParametersFactory createSqlParametersFactoryWithConverters(List converters) { BasicJdbcConverter converter = new BasicJdbcConverter(context, relationResolver, diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java index 9c9c8646ff..567eb57324 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java @@ -104,6 +104,7 @@ * @author Chirag Tailor * @author Diego Krupitza * @author Christopher Klein + * @author Mikhail Polivakha */ @Transactional @TestExecutionListeners(value = AssumeFeatureTestExecutionListener.class, mergeMode = MERGE_WITH_DEFAULTS) @@ -1242,8 +1243,9 @@ void fetchByExampleFluentOnlyInstantOneValueAsSimple() { assertThat(match.get().getName()).contains(two.getName()); } - @Test + @Test // GH-1405 void withDelimitedColumnTest() { + WithDelimitedColumn withDelimitedColumn = new WithDelimitedColumn(); withDelimitedColumn.setType("TYPICAL"); withDelimitedColumn.setIdentifier("UR-123");