Consider sanitised names when copying parameter sources.

Closes #1565
This commit is contained in:
Jens Schauder
2024-07-16 16:01:03 +02:00
parent 5916e9f473
commit 9214f9abb2
4 changed files with 85 additions and 2 deletions

View File

@@ -73,7 +73,7 @@ class SqlIdentifierParameterSource extends AbstractSqlParameterSource {
for (SqlIdentifier identifier : others.getIdentifiers()) {
String name = identifier.getReference();
String name = BindParameterNameSanitizer.sanitize( identifier.getReference());
addValue(identifier, others.getValue(name), others.getSqlType(name));
}
}

View File

@@ -61,6 +61,25 @@ class SqlIdentifierParameterSourceUnitTests {
});
}
@Test // GH-1565
void addSingleUnsanitaryValue() {
SqlIdentifierParameterSource parameters = new SqlIdentifierParameterSource();
parameters.addValue(SqlIdentifier.unquoted("ke.y"), 23);
assertSoftly(softly -> {
softly.assertThat(parameters.getParameterNames()).isEqualTo(new String[] { "key" });
softly.assertThat(parameters.getValue("key")).isEqualTo(23);
softly.assertThat(parameters.hasValue("key")).isTrue();
softly.assertThat(parameters.getValue("ke.y")).isNull();
softly.assertThat(parameters.hasValue("ke.y")).isFalse();
softly.assertThat(parameters.getSqlType("ke.y")).isEqualTo(Integer.MIN_VALUE);
});
}
@Test // DATAJDBC-386
void addSingleValueWithType() {
@@ -114,4 +133,38 @@ class SqlIdentifierParameterSourceUnitTests {
softly.assertThat(parameters.getSqlType("blah")).isEqualTo(Integer.MIN_VALUE);
});
}
@Test // DATAJDBC-386
void addOtherDatabaseObjectIdentifierParameterSourceWithUnsanitaryValue() {
SqlIdentifierParameterSource parameters = new SqlIdentifierParameterSource();
parameters.addValue(SqlIdentifier.unquoted("key1"), 111, 11);
parameters.addValue(SqlIdentifier.unquoted("key2"), 111);
SqlIdentifierParameterSource parameters2 = new SqlIdentifierParameterSource();
parameters2.addValue(SqlIdentifier.unquoted("key.2"), 222, 22);
parameters2.addValue(SqlIdentifier.unquoted("key.3"), 222);
parameters.addAll(parameters2);
assertSoftly(softly -> {
softly.assertThat(parameters.getParameterNames()).containsExactlyInAnyOrder("key1", "key2", "key3");
softly.assertThat(parameters.getValue("key1")).isEqualTo(111);
softly.assertThat(parameters.hasValue("key1")).isTrue();
softly.assertThat(parameters.getSqlType("key1")).isEqualTo(11);
softly.assertThat(parameters.getValue("key2")).isEqualTo(222);
softly.assertThat(parameters.hasValue("key2")).isTrue();
softly.assertThat(parameters.getSqlType("key2")).isEqualTo(22);
softly.assertThat(parameters.getValue("key3")).isEqualTo(222);
softly.assertThat(parameters.hasValue("key3")).isTrue();
softly.assertThat(parameters.getSqlType("key3")).isEqualTo(Integer.MIN_VALUE);
softly.assertThat(parameters.getValue("blah")).isNull();
softly.assertThat(parameters.hasValue("blah")).isFalse();
softly.assertThat(parameters.getSqlType("blah")).isEqualTo(Integer.MIN_VALUE);
});
}
}

View File

@@ -36,6 +36,7 @@ import org.springframework.data.relational.core.mapping.Embedded;
import org.springframework.data.relational.core.mapping.Embedded.OnEmpty;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.ListCrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.test.jdbc.JdbcTestUtils;
@@ -46,6 +47,7 @@ import org.springframework.test.jdbc.JdbcTestUtils;
* @author Bastian Wilhelm
* @author Christoph Strobl
* @author Mikhail Polivakha
* @author Jens Schauder
*/
@IntegrationTest
public class JdbcRepositoryEmbeddedIntegrationTests {
@@ -69,12 +71,18 @@ public class JdbcRepositoryEmbeddedIntegrationTests {
return factory.getRepository(WithDotColumnRepo.class);
}
@Bean
WithDotEmbeddedRepo withDotEmbeddedRepo(JdbcRepositoryFactory factory) {
return factory.getRepository(WithDotEmbeddedRepo.class);
}
}
@Autowired NamedParameterJdbcTemplate template;
@Autowired DummyEntityRepository repository;
@Autowired PersonRepository personRepository;
@Autowired WithDotColumnRepo withDotColumnRepo;
@Autowired WithDotEmbeddedRepo withDotEmbeddedRepo;
@Test // DATAJDBC-111
void savesAnEntity() {
@@ -270,6 +278,16 @@ public class JdbcRepositoryEmbeddedIntegrationTests {
Assertions.assertThat(fetchedPersons).containsExactly(saved.get(1), saved.get(0), saved.get(2));
}
@Test // GH-1565
void saveAndLoadEmbeddedWithDottedPrefix() {
WithDotEmbedded entity = withDotEmbeddedRepo.save(
new WithDotEmbedded(null, new PersonContacts("jens@jens.de", "123456789")));
WithDotEmbedded reloaded = withDotEmbeddedRepo.findById(entity.id).orElseThrow();
assertThat(reloaded).isEqualTo(entity);
}
private static DummyEntity createDummyEntity() {
DummyEntity entity = new DummyEntity();
@@ -304,6 +322,11 @@ public class JdbcRepositoryEmbeddedIntegrationTests {
record WithDotColumn(@Id Integer id, @Column("address.city") String address) {
}
record WithDotEmbedded(@Id Integer id, @Embedded.Nullable(prefix = "prefix.") PersonContacts contact) {
}
interface WithDotEmbeddedRepo extends ListCrudRepository<WithDotEmbedded, Integer> {}
@Table("SORT_EMBEDDED_ENTITY")
record Person(@Id Long id, String firstName, String address, @Embedded.Nullable PersonContacts personContacts) {
}

View File

@@ -20,4 +20,11 @@ CREATE TABLE WITH_DOT_COLUMN
(
id BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
"address.city" VARCHAR(255)
);
);
CREATE TABLE WITH_DOT_EMBEDDED
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
"PREFIX.EMAIL" VARCHAR(255),
"PREFIX.PHONE_NUMBER" VARCHAR(255)
)