From c78bfae44a0983422f7654beff2d7c1f4733be1c Mon Sep 17 00:00:00 2001 From: Bastian Wilhelm Date: Mon, 18 Feb 2019 17:34:11 +0100 Subject: [PATCH] DATAJDBC-334 - Fixes broken parameter names for quoted column names. When a column has a quoted name it contains characters illegal for parameter names. Therefore the parameter names now get sanitised. Compared to the version on master testing is more lenient. This accounts for the SqlGenerator behaving slightly different then on master. Original pull request: #120. See also: https://jira.spring.io/browse/DATAJDBC-262. --- .../data/jdbc/core/SqlGenerator.java | 14 ++++++++-- .../data/jdbc/core/SqlGeneratorUnitTests.java | 28 +++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java b/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java index 71dc86e4..4e8e9673 100644 --- a/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java +++ b/src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java @@ -21,6 +21,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; @@ -40,6 +41,7 @@ import org.springframework.util.Assert; * * @author Jens Schauder * @author Yoichi Imai + * @author Bastian Wilhelm */ class SqlGenerator { @@ -61,6 +63,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) { @@ -263,6 +267,7 @@ class SqlGenerator { String tableColumns = String.join(", ", columnNamesForInsert); String parameterNames = columnNamesForInsert.stream()// + .map(this::columnNameToParameterName) .map(n -> String.format(":%s", n))// .collect(Collectors.joining(", ")); @@ -274,10 +279,11 @@ class SqlGenerator { String updateTemplate = "UPDATE %s SET %s WHERE %s = :%s"; String setClause = columnNames.stream()// - .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() { @@ -349,4 +355,8 @@ class SqlGenerator { entity.getTableName(), innerCondition // ); } + + private String columnNameToParameterName(String columnName){ + return parameterPattern.matcher(columnName).replaceAll(""); + } } diff --git a/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java b/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java index 296fdcfb..66964e00 100644 --- a/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java +++ b/src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java @@ -38,6 +38,7 @@ import org.springframework.data.relational.core.mapping.RelationalPersistentProp * * @author Jens Schauder * @author Greg Turnquist + * @author Bastian Wilhelm */ public class SqlGeneratorUnitTests { @@ -189,6 +190,26 @@ 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-334 + public void getUpdateForQuotedColumnName() { + SqlGenerator sqlGenerator = createSqlGenerator(EntityWithQuotedColumnName.class); + + String update = sqlGenerator.getUpdate(); + + assertThat(update).startsWith("UPDATE entity_with_quoted_column_name " + "SET ") + .endsWith("\"test_@123\" = :test_123 " + "WHERE \"test_@id\" = :test_id"); + } + private PersistentPropertyPath getPath(String path, Class base) { return PersistentPropertyPathTestUtils.getPath(context, path, base); } @@ -196,8 +217,7 @@ public class SqlGeneratorUnitTests { @SuppressWarnings("unused") static class DummyEntity { - @Column("id1") - @Id Long id; + @Column("id1") @Id Long id; String name; ReferencedEntity ref; Set elements; @@ -239,4 +259,8 @@ public class SqlGeneratorUnitTests { @Id Long id; } + static class EntityWithQuotedColumnName { + @Id @Column("\"test_@id\"") Long id; + @Column("\"test_@123\"") String name; + } }