Skip to content

Commit ab7bf64

Browse files
committed
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 <[email protected]>
1 parent ca45cd5 commit ab7bf64

File tree

3 files changed

+99
-3
lines changed

3 files changed

+99
-3
lines changed

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,16 @@ private void deleteRelations(RelationalPersistentEntity<?> entity, Select parent
150150

151151
Condition inCondition = Conditions.in(expression, parentSelect);
152152

153-
List<Column> parentIdColumns = aggregatePath.getIdDefiningParentPath().getTableInfo().idColumnInfos()
154-
.toColumnList(table);
153+
List<Column> idColumns = aggregatePath.getTableInfo().idColumnInfos()
154+
.toColumnList(table);
155+
156+
if (idColumns.isEmpty()) {
157+
idColumns = aggregatePath.getIdDefiningParentPath().getTableInfo().idColumnInfos()
158+
.toColumnList(table);
159+
}
155160

156161
Select select = StatementBuilder.select( //
157-
parentIdColumns //
162+
idColumns //
158163
).from(table) //
159164
.where(inCondition) //
160165
.build();

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.springframework.context.annotation.Configuration;
1313
import org.springframework.context.annotation.Import;
1414
import org.springframework.data.annotation.Id;
15+
import org.springframework.data.relational.core.mapping.Column;
1516
import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactory;
1617
import org.springframework.data.jdbc.testing.DatabaseType;
1718
import org.springframework.data.jdbc.testing.EnabledOnDatabase;
@@ -32,6 +33,7 @@ class JdbcRepositoryWithCollectionsChainHsqlIntegrationTests {
3233

3334
@Autowired NamedParameterJdbcTemplate template;
3435
@Autowired DummyEntityRepository repository;
36+
@Autowired CustomIdDummyEntityRepository customIdRepository;
3537

3638
private static DummyEntity createDummyEntity() {
3739

@@ -40,6 +42,13 @@ private static DummyEntity createDummyEntity() {
4042
return entity;
4143
}
4244

45+
private static CustomIdDummyEntity createCustomIdDummyEntity() {
46+
47+
CustomIdDummyEntity entity = new CustomIdDummyEntity();
48+
entity.name = "Custom ID Entity Name";
49+
return entity;
50+
}
51+
4352
@Test // DATAJDBC-551
4453
void deleteByName() {
4554

@@ -60,6 +69,26 @@ void deleteByName() {
6069
assertThat(count).isEqualTo(0);
6170
}
6271

72+
@Test // DATAJDBC-2123
73+
void deleteByNameWithCustomIdColumn() {
74+
75+
CustomIdChildElement element1 = createCustomIdChildElement("one");
76+
CustomIdChildElement element2 = createCustomIdChildElement("two");
77+
78+
CustomIdDummyEntity entity = createCustomIdDummyEntity();
79+
entity.content.add(element1);
80+
entity.content.add(element2);
81+
82+
entity = customIdRepository.save(entity);
83+
84+
assertThat(customIdRepository.deleteByName("Custom ID Entity Name")).isEqualTo(1);
85+
86+
assertThat(customIdRepository.findById(entity.id)).isEmpty();
87+
88+
Long count = template.queryForObject("select count(1) from custom_id_grand_child_element", new HashMap<>(), Long.class);
89+
assertThat(count).isEqualTo(0);
90+
}
91+
6392
private ChildElement createChildElement(String name) {
6493

6594
ChildElement element = new ChildElement();
@@ -76,10 +105,30 @@ private GrandChildElement createGrandChildElement(String content) {
76105
return element;
77106
}
78107

108+
private CustomIdChildElement createCustomIdChildElement(String name) {
109+
110+
CustomIdChildElement element = new CustomIdChildElement();
111+
element.name = name;
112+
element.content.add(createCustomIdGrandChildElement(name + "1"));
113+
element.content.add(createCustomIdGrandChildElement(name + "2"));
114+
return element;
115+
}
116+
117+
private CustomIdGrandChildElement createCustomIdGrandChildElement(String content) {
118+
119+
CustomIdGrandChildElement element = new CustomIdGrandChildElement();
120+
element.content = content;
121+
return element;
122+
}
123+
79124
interface DummyEntityRepository extends CrudRepository<DummyEntity, Long> {
80125
long deleteByName(String name);
81126
}
82127

128+
interface CustomIdDummyEntityRepository extends CrudRepository<CustomIdDummyEntity, Long> {
129+
long deleteByName(String name);
130+
}
131+
83132
@Configuration
84133
@Import(TestConfiguration.class)
85134
static class Config {
@@ -95,6 +144,11 @@ Class<?> testClass() {
95144
DummyEntityRepository dummyEntityRepository() {
96145
return factory.getRepository(DummyEntityRepository.class);
97146
}
147+
148+
@Bean
149+
CustomIdDummyEntityRepository customIdDummyEntityRepository() {
150+
return factory.getRepository(CustomIdDummyEntityRepository.class);
151+
}
98152
}
99153

100154
static class DummyEntity {
@@ -118,4 +172,24 @@ static class GrandChildElement {
118172
@Id private Long id;
119173
}
120174

175+
static class CustomIdDummyEntity {
176+
177+
String name;
178+
Set<CustomIdChildElement> content = new HashSet<>();
179+
@Id private Long id;
180+
}
181+
182+
static class CustomIdChildElement {
183+
184+
String name;
185+
Set<CustomIdGrandChildElement> content = new HashSet<>();
186+
@Id @Column("CHILD_ID") private Long id;
187+
}
188+
189+
static class CustomIdGrandChildElement {
190+
191+
String content;
192+
@Id private Long id;
193+
}
194+
121195
}

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,20 @@ CREATE TABLE GRAND_CHILD_ELEMENT
1515
CONTENT VARCHAR(100),
1616
CHILD_ELEMENT BIGINT
1717
);
18+
CREATE TABLE CUSTOM_ID_DUMMY_ENTITY
19+
(
20+
ID BIGINT GENERATED BY DEFAULT AS IDENTITY ( START WITH 1 ) PRIMARY KEY,
21+
NAME VARCHAR(100)
22+
);
23+
CREATE TABLE CUSTOM_ID_CHILD_ELEMENT
24+
(
25+
CHILD_ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
26+
NAME VARCHAR(100),
27+
CUSTOM_ID_DUMMY_ENTITY BIGINT
28+
);
29+
CREATE TABLE CUSTOM_ID_GRAND_CHILD_ELEMENT
30+
(
31+
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
32+
CONTENT VARCHAR(100),
33+
CUSTOM_ID_CHILD_ELEMENT BIGINT
34+
);

0 commit comments

Comments
 (0)