Browse Source

DATAJDBC-144 - Using correct column names from NamingStrategy.

The list of columns used in the SqlGenerator contained property names instead of column names, leading to errors when a non-trivial NamingStrategy was used.
pull/17/merge
Jens Schauder 8 years ago committed by Greg Turnquist
parent
commit
482f330f02
No known key found for this signature in database
GPG Key ID: CB2FA4D512B5C413
  1. 22
      src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java
  2. 24
      src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java
  3. 2
      src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java
  4. 8
      src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java

22
src/main/java/org/springframework/data/jdbc/core/SqlGenerator.java

@ -43,8 +43,8 @@ class SqlGenerator {
private final JdbcPersistentEntity<?> entity; private final JdbcPersistentEntity<?> entity;
private final JdbcMappingContext context; private final JdbcMappingContext context;
private final List<String> propertyNames = new ArrayList<>(); private final List<String> columnNames = new ArrayList<>();
private final List<String> nonIdPropertyNames = new ArrayList<>(); private final List<String> nonIdColumnNames = new ArrayList<>();
private final Lazy<String> findOneSql = Lazy.of(this::createFindOneSelectSql); private final Lazy<String> findOneSql = Lazy.of(this::createFindOneSelectSql);
private final Lazy<String> findAllSql = Lazy.of(this::createFindAllSql); private final Lazy<String> findAllSql = Lazy.of(this::createFindAllSql);
@ -64,17 +64,17 @@ class SqlGenerator {
this.context = context; this.context = context;
this.entity = entity; this.entity = entity;
this.sqlGeneratorSource = sqlGeneratorSource; this.sqlGeneratorSource = sqlGeneratorSource;
initPropertyNames(); initColumnNames();
} }
private void initPropertyNames() { private void initColumnNames() {
entity.doWithProperties((PropertyHandler<JdbcPersistentProperty>) p -> { entity.doWithProperties((PropertyHandler<JdbcPersistentProperty>) p -> {
// the referencing column of referenced entity is expected to be on the other side of the relation // the referencing column of referenced entity is expected to be on the other side of the relation
if (!p.isEntity()) { if (!p.isEntity()) {
propertyNames.add(p.getName()); columnNames.add(p.getColumnName());
if (!entity.isIdProperty(p)) { if (!entity.isIdProperty(p)) {
nonIdPropertyNames.add(p.getName()); nonIdColumnNames.add(p.getColumnName());
} }
} }
}); });
@ -211,11 +211,11 @@ class SqlGenerator {
String insertTemplate = "insert into %s (%s) values (%s)"; String insertTemplate = "insert into %s (%s) values (%s)";
List<String> propertyNamesForInsert = new ArrayList<>(excludeId ? nonIdPropertyNames : propertyNames); List<String> columnNamesForInsert = new ArrayList<>(excludeId ? nonIdColumnNames : columnNames);
propertyNamesForInsert.addAll(additionalColumns); columnNamesForInsert.addAll(additionalColumns);
String tableColumns = String.join(", ", propertyNamesForInsert); String tableColumns = String.join(", ", columnNamesForInsert);
String parameterNames = propertyNamesForInsert.stream().collect(Collectors.joining(", :", ":", "")); String parameterNames = columnNamesForInsert.stream().collect(Collectors.joining(", :", ":", ""));
return String.format(insertTemplate, entity.getTableName(), tableColumns, parameterNames); return String.format(insertTemplate, entity.getTableName(), tableColumns, parameterNames);
} }
@ -224,7 +224,7 @@ class SqlGenerator {
String updateTemplate = "update %s set %s where %s = :%s"; String updateTemplate = "update %s set %s where %s = :%s";
String setClause = propertyNames.stream()// String setClause = columnNames.stream()//
.map(n -> String.format("%s = :%s", n, n))// .map(n -> String.format("%s = :%s", n, n))//
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));

24
src/test/java/org/springframework/data/jdbc/core/SqlGeneratorUnitTests.java

@ -26,6 +26,7 @@ import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.mapping.model.DefaultNamingStrategy; import org.springframework.data.jdbc.mapping.model.DefaultNamingStrategy;
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext; import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity; import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty;
import org.springframework.data.jdbc.mapping.model.NamingStrategy; import org.springframework.data.jdbc.mapping.model.NamingStrategy;
import org.springframework.data.mapping.PropertyPath; import org.springframework.data.mapping.PropertyPath;
@ -42,7 +43,7 @@ public class SqlGeneratorUnitTests {
@Before @Before
public void setUp() { public void setUp() {
NamingStrategy namingStrategy = new DefaultNamingStrategy(); NamingStrategy namingStrategy = new PrefixingNamingStrategy();
JdbcMappingContext context = new JdbcMappingContext(namingStrategy); JdbcMappingContext context = new JdbcMappingContext(namingStrategy);
JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class); JdbcPersistentEntity<?> persistentEntity = context.getRequiredPersistentEntity(DummyEntity.class);
this.sqlGenerator = new SqlGenerator(context, persistentEntity, new SqlGeneratorSource(context)); this.sqlGenerator = new SqlGenerator(context, persistentEntity, new SqlGeneratorSource(context));
@ -56,10 +57,10 @@ public class SqlGeneratorUnitTests {
SoftAssertions softAssertions = new SoftAssertions(); SoftAssertions softAssertions = new SoftAssertions();
softAssertions.assertThat(sql) // softAssertions.assertThat(sql) //
.startsWith("SELECT") // .startsWith("SELECT") //
.contains("DummyEntity.id AS id,") // .contains("DummyEntity.x_id AS x_id,") //
.contains("DummyEntity.name AS name,") // .contains("DummyEntity.x_name AS x_name,") //
.contains("ref.l1id AS ref_l1id") // .contains("ref.x_l1id AS ref_x_l1id") //
.contains("ref.content AS ref_content").contains(" FROM DummyEntity") // .contains("ref.x_content AS ref_x_content").contains(" FROM DummyEntity") //
// 1-N relationships do not get loaded via join // 1-N relationships do not get loaded via join
.doesNotContain("Element AS elements"); .doesNotContain("Element AS elements");
softAssertions.assertAll(); softAssertions.assertAll();
@ -79,7 +80,7 @@ public class SqlGeneratorUnitTests {
String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref.further", DummyEntity.class)); String sql = sqlGenerator.createDeleteByPath(PropertyPath.from("ref.further", DummyEntity.class));
assertThat(sql).isEqualTo( assertThat(sql).isEqualTo(
"DELETE FROM SecondLevelReferencedEntity WHERE ReferencedEntity IN (SELECT l1id FROM ReferencedEntity WHERE DummyEntity = :rootId)"); "DELETE FROM SecondLevelReferencedEntity WHERE ReferencedEntity IN (SELECT x_l1id FROM ReferencedEntity WHERE DummyEntity = :rootId)");
} }
@Test // DATAJDBC-112 @Test // DATAJDBC-112
@ -104,7 +105,7 @@ public class SqlGeneratorUnitTests {
String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref.further", DummyEntity.class)); String sql = sqlGenerator.createDeleteAllSql(PropertyPath.from("ref.further", DummyEntity.class));
assertThat(sql).isEqualTo( assertThat(sql).isEqualTo(
"DELETE FROM SecondLevelReferencedEntity WHERE ReferencedEntity IN (SELECT l1id FROM ReferencedEntity WHERE DummyEntity IS NOT NULL)"); "DELETE FROM SecondLevelReferencedEntity WHERE ReferencedEntity IN (SELECT x_l1id FROM ReferencedEntity WHERE DummyEntity IS NOT NULL)");
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -135,4 +136,13 @@ public class SqlGeneratorUnitTests {
@Id Long id; @Id Long id;
String content; String content;
} }
private static class PrefixingNamingStrategy extends DefaultNamingStrategy {
@Override
public String getColumnName(JdbcPersistentProperty property) {
return "x_" + super.getColumnName(property);
}
}
} }

2
src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryIntegrationTests.java

@ -63,8 +63,10 @@ public class JdbcRepositoryIntegrationTests {
DummyEntityRepository dummyEntityRepository() { DummyEntityRepository dummyEntityRepository() {
return factory.getRepository(DummyEntityRepository.class); return factory.getRepository(DummyEntityRepository.class);
} }
} }
@ClassRule public static final SpringClassRule classRule = new SpringClassRule(); @ClassRule public static final SpringClassRule classRule = new SpringClassRule();
@Rule public SpringMethodRule methodRule = new SpringMethodRule(); @Rule public SpringMethodRule methodRule = new SpringMethodRule();

8
src/test/java/org/springframework/data/jdbc/testing/TestConfiguration.java

@ -27,6 +27,7 @@ import org.springframework.data.jdbc.core.DefaultDataAccessStrategy;
import org.springframework.data.jdbc.core.SqlGeneratorSource; import org.springframework.data.jdbc.core.SqlGeneratorSource;
import org.springframework.data.jdbc.mapping.model.DefaultNamingStrategy; import org.springframework.data.jdbc.mapping.model.DefaultNamingStrategy;
import org.springframework.data.jdbc.mapping.model.JdbcMappingContext; import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory; import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DataSourceTransactionManager;
@ -49,7 +50,12 @@ public class TestConfiguration {
@Bean @Bean
JdbcRepositoryFactory jdbcRepositoryFactory() { JdbcRepositoryFactory jdbcRepositoryFactory() {
final JdbcMappingContext context = new JdbcMappingContext(new DefaultNamingStrategy()); final JdbcMappingContext context = new JdbcMappingContext(new DefaultNamingStrategy(){
@Override
public String getColumnName(JdbcPersistentProperty property) {
return super.getColumnName(property);
}
});
return new JdbcRepositoryFactory( // return new JdbcRepositoryFactory( //
publisher, // publisher, //

Loading…
Cancel
Save