diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java index dc2a8f118..1aecf62ad 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java @@ -22,6 +22,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -66,6 +67,8 @@ class SqlGenerator { private final Lazy deleteByListSql = Lazy.of(this::createDeleteByListSql); private final SqlGeneratorSource sqlGeneratorSource; + private final Pattern parameterPattern = Pattern.compile("\\W"); + SqlGenerator(RelationalMappingContext context, RelationalPersistentEntity entity, SqlGeneratorSource sqlGeneratorSource) { @@ -340,6 +343,7 @@ class SqlGenerator { String tableColumns = String.join(", ", columnNamesForInsert); String parameterNames = columnNamesForInsert.stream()// + .map(this::columnNameToParameterName) .map(n -> String.format(":%s", n))// .collect(Collectors.joining(", ")); @@ -353,10 +357,11 @@ class SqlGenerator { String setClause = columnNames.stream() // .filter(s -> !s.equals(entity.getIdColumn())) // .filter(s -> !readOnlyColumnNames.contains(s)) // - .map(n -> String.format("%s = :%s", n, n)) // + .map(n -> String.format("%s = :%s", n, columnNameToParameterName(n))) // .collect(Collectors.joining(", ")); - return String.format(updateTemplate, entity.getTableName(), setClause, entity.getIdColumn(), entity.getIdColumn()); + return String.format(updateTemplate, entity.getTableName(), setClause, entity.getIdColumn(), + columnNameToParameterName(entity.getIdColumn())); } private String createDeleteSql() { @@ -447,4 +452,8 @@ class SqlGenerator { entity.getTableName(), innerCondition // ); } + + private String columnNameToParameterName(String columnName){ + return parameterPattern.matcher(columnName).replaceAll(""); + } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java index 38944dd6d..3211312d4 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java @@ -42,6 +42,7 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProp * @author Jens Schauder * @author Greg Turnquist * @author Oleksandr Kucher + * @author Bastian Wilhelm */ public class SqlGeneratorUnitTests { @@ -206,6 +207,17 @@ public class SqlGeneratorUnitTests { assertThat(insert).endsWith("()"); } + @Test // DATAJDBC-334 + public void getInsertForQuotedColumnName() { + SqlGenerator sqlGenerator = createSqlGenerator(EntityWithQuotedColumnName.class); + + String insert = sqlGenerator.getInsert(emptySet()); + + assertThat(insert).isEqualTo("INSERT INTO entity_with_quoted_column_name " + + "(\"test_@123\") " + + "VALUES (:test_123)"); + } + @Test // DATAJDBC-266 public void joinForOneToOneWithoutIdIncludesTheBackReferenceOfTheOuterJoin() { @@ -240,6 +252,17 @@ public class SqlGeneratorUnitTests { ); } + @Test // DATAJDBC-334 + public void getUpdateForQuotedColumnName() { + SqlGenerator sqlGenerator = createSqlGenerator(EntityWithQuotedColumnName.class); + + String update = sqlGenerator.getUpdate(); + + assertThat(update).isEqualTo("UPDATE entity_with_quoted_column_name " + + "SET \"test_@123\" = :test_123 " + + "WHERE \"test_@id\" = :test_id"); + } + @Test // DATAJDBC-324 public void readOnlyPropertyExcludedFromQuery_when_generateInsertSql() { @@ -378,4 +401,9 @@ public class SqlGeneratorUnitTests { String name; @ReadOnlyProperty String readOnlyValue; } + + static class EntityWithQuotedColumnName { + @Id @Column("\"test_@id\"") Long id; + @Column("\"test_@123\"") String name; + } }