Browse Source

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.
pull/126/head
Bastian Wilhelm 7 years ago committed by Jens Schauder
parent
commit
c78bfae44a
  1. 14
      src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java
  2. 28
      src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java

14
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.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -40,6 +41,7 @@ import org.springframework.util.Assert;
* *
* @author Jens Schauder * @author Jens Schauder
* @author Yoichi Imai * @author Yoichi Imai
* @author Bastian Wilhelm
*/ */
class SqlGenerator { class SqlGenerator {
@ -61,6 +63,8 @@ class SqlGenerator {
private final Lazy<String> deleteByListSql = Lazy.of(this::createDeleteByListSql); private final Lazy<String> deleteByListSql = Lazy.of(this::createDeleteByListSql);
private final SqlGeneratorSource sqlGeneratorSource; private final SqlGeneratorSource sqlGeneratorSource;
private final Pattern parameterPattern = Pattern.compile("\\W");
SqlGenerator(RelationalMappingContext context, RelationalPersistentEntity<?> entity, SqlGenerator(RelationalMappingContext context, RelationalPersistentEntity<?> entity,
SqlGeneratorSource sqlGeneratorSource) { SqlGeneratorSource sqlGeneratorSource) {
@ -263,6 +267,7 @@ class SqlGenerator {
String tableColumns = String.join(", ", columnNamesForInsert); String tableColumns = String.join(", ", columnNamesForInsert);
String parameterNames = columnNamesForInsert.stream()// String parameterNames = columnNamesForInsert.stream()//
.map(this::columnNameToParameterName)
.map(n -> String.format(":%s", n))// .map(n -> String.format(":%s", n))//
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));
@ -274,10 +279,11 @@ class SqlGenerator {
String updateTemplate = "UPDATE %s SET %s WHERE %s = :%s"; String updateTemplate = "UPDATE %s SET %s WHERE %s = :%s";
String setClause = columnNames.stream()// String setClause = columnNames.stream()//
.map(n -> String.format("%s = :%s", n, n))// .map(n -> String.format("%s = :%s", n, columnNameToParameterName(n))) //
.collect(Collectors.joining(", ")); .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() { private String createDeleteSql() {
@ -349,4 +355,8 @@ class SqlGenerator {
entity.getTableName(), innerCondition // entity.getTableName(), innerCondition //
); );
} }
private String columnNameToParameterName(String columnName){
return parameterPattern.matcher(columnName).replaceAll("");
}
} }

28
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 Jens Schauder
* @author Greg Turnquist * @author Greg Turnquist
* @author Bastian Wilhelm
*/ */
public class SqlGeneratorUnitTests { public class SqlGeneratorUnitTests {
@ -189,6 +190,26 @@ public class SqlGeneratorUnitTests {
assertThat(insert).endsWith("()"); 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<RelationalPersistentProperty> getPath(String path, Class<?> base) { private PersistentPropertyPath<RelationalPersistentProperty> getPath(String path, Class<?> base) {
return PersistentPropertyPathTestUtils.getPath(context, path, base); return PersistentPropertyPathTestUtils.getPath(context, path, base);
} }
@ -196,8 +217,7 @@ public class SqlGeneratorUnitTests {
@SuppressWarnings("unused") @SuppressWarnings("unused")
static class DummyEntity { static class DummyEntity {
@Column("id1") @Column("id1") @Id Long id;
@Id Long id;
String name; String name;
ReferencedEntity ref; ReferencedEntity ref;
Set<Element> elements; Set<Element> elements;
@ -239,4 +259,8 @@ public class SqlGeneratorUnitTests {
@Id Long id; @Id Long id;
} }
static class EntityWithQuotedColumnName {
@Id @Column("\"test_@id\"") Long id;
@Column("\"test_@123\"") String name;
}
} }

Loading…
Cancel
Save