Browse Source

Fix DELETE queries with custom @Column ID names

- Support @Column annotation on ID fields when deleting collection entities
- Fallback to parent path IDs for embedded collections
- Add test for custom ID column DELETE operations

Fixes DATAJDBC-2123
Signed-off-by: Huiyeongkim <huiyeong9619@naver.com>
pull/2128/head
Huiyeongkim 5 months ago
parent
commit
ab7bf64b57
  1. 11
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcDeleteQueryCreator.java
  2. 74
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryWithCollectionsChainHsqlIntegrationTests.java
  3. 17
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithCollectionsChainHsqlIntegrationTests-hsql.sql

11
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/JdbcDeleteQueryCreator.java

@ -150,11 +150,16 @@ class JdbcDeleteQueryCreator extends RelationalQueryCreator<List<ParametrizedQue @@ -150,11 +150,16 @@ class JdbcDeleteQueryCreator extends RelationalQueryCreator<List<ParametrizedQue
Condition inCondition = Conditions.in(expression, parentSelect);
List<Column> parentIdColumns = aggregatePath.getIdDefiningParentPath().getTableInfo().idColumnInfos()
.toColumnList(table);
List<Column> idColumns = aggregatePath.getTableInfo().idColumnInfos()
.toColumnList(table);
if (idColumns.isEmpty()) {
idColumns = aggregatePath.getIdDefiningParentPath().getTableInfo().idColumnInfos()
.toColumnList(table);
}
Select select = StatementBuilder.select( //
parentIdColumns //
idColumns //
).from(table) //
.where(inCondition) //
.build();

74
spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryWithCollectionsChainHsqlIntegrationTests.java

@ -12,6 +12,7 @@ import org.springframework.context.annotation.Bean; @@ -12,6 +12,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
import org.springframework.data.jdbc.testing.DatabaseType;
import org.springframework.data.jdbc.testing.EnabledOnDatabase;
@ -32,6 +33,7 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests { @@ -32,6 +33,7 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests {
@Autowired NamedParameterJdbcTemplate template;
@Autowired DummyEntityRepository repository;
@Autowired CustomIdDummyEntityRepository customIdRepository;
private static DummyEntity createDummyEntity() {
@ -40,6 +42,13 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests { @@ -40,6 +42,13 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests {
return entity;
}
private static CustomIdDummyEntity createCustomIdDummyEntity() {
CustomIdDummyEntity entity = new CustomIdDummyEntity();
entity.name = "Custom ID Entity Name";
return entity;
}
@Test // DATAJDBC-551
void deleteByName() {
@ -60,6 +69,26 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests { @@ -60,6 +69,26 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests {
assertThat(count).isEqualTo(0);
}
@Test // DATAJDBC-2123
void deleteByNameWithCustomIdColumn() {
CustomIdChildElement element1 = createCustomIdChildElement("one");
CustomIdChildElement element2 = createCustomIdChildElement("two");
CustomIdDummyEntity entity = createCustomIdDummyEntity();
entity.content.add(element1);
entity.content.add(element2);
entity = customIdRepository.save(entity);
assertThat(customIdRepository.deleteByName("Custom ID Entity Name")).isEqualTo(1);
assertThat(customIdRepository.findById(entity.id)).isEmpty();
Long count = template.queryForObject("select count(1) from custom_id_grand_child_element", new HashMap<>(), Long.class);
assertThat(count).isEqualTo(0);
}
private ChildElement createChildElement(String name) {
ChildElement element = new ChildElement();
@ -76,10 +105,30 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests { @@ -76,10 +105,30 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests {
return element;
}
private CustomIdChildElement createCustomIdChildElement(String name) {
CustomIdChildElement element = new CustomIdChildElement();
element.name = name;
element.content.add(createCustomIdGrandChildElement(name + "1"));
element.content.add(createCustomIdGrandChildElement(name + "2"));
return element;
}
private CustomIdGrandChildElement createCustomIdGrandChildElement(String content) {
CustomIdGrandChildElement element = new CustomIdGrandChildElement();
element.content = content;
return element;
}
interface DummyEntityRepository extends CrudRepository<DummyEntity, Long> {
long deleteByName(String name);
}
interface CustomIdDummyEntityRepository extends CrudRepository<CustomIdDummyEntity, Long> {
long deleteByName(String name);
}
@Configuration
@Import(TestConfiguration.class)
static class Config {
@ -95,6 +144,11 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests { @@ -95,6 +144,11 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests {
DummyEntityRepository dummyEntityRepository() {
return factory.getRepository(DummyEntityRepository.class);
}
@Bean
CustomIdDummyEntityRepository customIdDummyEntityRepository() {
return factory.getRepository(CustomIdDummyEntityRepository.class);
}
}
static class DummyEntity {
@ -118,4 +172,24 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests { @@ -118,4 +172,24 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests {
@Id private Long id;
}
static class CustomIdDummyEntity {
String name;
Set<CustomIdChildElement> content = new HashSet<>();
@Id private Long id;
}
static class CustomIdChildElement {
String name;
Set<CustomIdGrandChildElement> content = new HashSet<>();
@Id @Column("CHILD_ID") private Long id;
}
static class CustomIdGrandChildElement {
String content;
@Id private Long id;
}
}

17
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryWithCollectionsChainHsqlIntegrationTests-hsql.sql

@ -15,3 +15,20 @@ CREATE TABLE GRAND_CHILD_ELEMENT @@ -15,3 +15,20 @@ CREATE TABLE GRAND_CHILD_ELEMENT
CONTENT VARCHAR(100),
CHILD_ELEMENT BIGINT
);
CREATE TABLE CUSTOM_ID_DUMMY_ENTITY
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
NAME VARCHAR(100)
);
CREATE TABLE CUSTOM_ID_CHILD_ELEMENT
(
CHILD_ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
NAME VARCHAR(100),
CUSTOM_ID_DUMMY_ENTITY BIGINT
);
CREATE TABLE CUSTOM_ID_GRAND_CHILD_ELEMENT
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
CONTENT VARCHAR(100),
CUSTOM_ID_CHILD_ELEMENT BIGINT
);

Loading…
Cancel
Save