Skip to content

Commit b063663

Browse files
schaudermp911de
authored andcommitted
Properly convert Map keys.
Keys of maps now get properly converted. Among others this enables the use of enums as keys. Closes #1656 Original pull request: #1663
1 parent 9238f39 commit b063663

11 files changed

+185
-33
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ private Object getIdFrom(DbAction.WithEntity<?> idOwningAction) {
245245
RelationalPersistentEntity<?> persistentEntity = getRequiredPersistentEntity(idOwningAction.getEntityType());
246246
Object identifier = persistentEntity.getIdentifierAccessor(idOwningAction.getEntity()).getIdentifier();
247247

248-
Assert.state(identifier != null, "Couldn't obtain a required id value");
248+
Assert.state(identifier != null,() -> "Couldn't obtain a required id value for " + persistentEntity);
249249

250250
return identifier;
251251
}

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MapEntityRowMapper.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
2424
import org.springframework.data.relational.core.sql.IdentifierProcessing;
2525
import org.springframework.data.relational.core.sql.SqlIdentifier;
26+
import org.springframework.data.util.TypeInformation;
2627
import org.springframework.jdbc.core.RowMapper;
28+
import org.springframework.jdbc.support.JdbcUtils;
2729

2830
/**
2931
* A {@link RowMapper} that maps a row to a {@link Map.Entry} so an {@link Iterable} of those can be converted to a
@@ -50,8 +52,11 @@ class MapEntityRowMapper<T> implements RowMapper<Map.Entry<Object, T>> {
5052
@Override
5153
public Map.Entry<Object, T> mapRow(ResultSet rs, int rowNum) throws SQLException {
5254

53-
Object key = rs.getObject(keyColumn.getReference());
54-
return new HashMap.SimpleEntry<>(key, mapEntity(rs, key));
55+
Object key = new ResultSetAccessor(rs).getObject(keyColumn.getReference());
56+
Class<?> qualifierColumnType = path.getRequiredPersistentPropertyPath().getLeafProperty().getQualifierColumnType();
57+
Object convertedKey = converter.readValue(key, TypeInformation.of(qualifierColumnType));
58+
59+
return new HashMap.SimpleEntry<>(convertedKey, mapEntity(rs, key));
5560
}
5661

5762
private T mapEntity(ResultSet resultSet, Object key) {

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,16 @@ void readEnumArray() {
10951095
assertThat(template.findById(entity.id, EnumArrayOwner.class).digits).isEqualTo(new Color[]{Color.BLUE});
10961096
}
10971097

1098+
@Test // GH-1656
1099+
void mapWithEnumKey() {
1100+
1101+
EnumMapOwner enumMapOwner = template.save(new EnumMapOwner(null, "OwnerName", Map.of(Color.BLUE, new MapElement("Element"))));
1102+
1103+
Iterable<EnumMapOwner> enumMapOwners = template.findAll(EnumMapOwner.class);
1104+
1105+
assertThat(enumMapOwners).containsExactly(enumMapOwner);
1106+
}
1107+
10981108
private <T extends Number> void saveAndUpdateAggregateWithVersion(VersionedAggregate aggregate,
10991109
Function<Number, T> toConcreteNumber) {
11001110
saveAndUpdateAggregateWithVersion(aggregate, toConcreteNumber, 0);
@@ -1548,6 +1558,12 @@ static class WithInsertOnly {
15481558
String insertOnly;
15491559
}
15501560

1561+
record EnumMapOwner(@Id Long id, String name, Map<Color, MapElement> map) {
1562+
}
1563+
1564+
record MapElement(String name) {
1565+
}
1566+
15511567
@Configuration
15521568
@Import(TestConfiguration.class)
15531569
static class Config {

spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-db2.sql

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,17 @@ DROP TABLE WITH_ID_ONLY;
4141

4242
DROP TABLE WITH_INSERT_ONLY;
4343

44+
DROP TABLE MAP_ELEMENT;
45+
DROP TABLE ENUM_MAP_OWNER;
46+
4447
CREATE TABLE LEGO_SET
4548
(
46-
"id1" BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
47-
NAME VARCHAR(30)
49+
"id1" BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
50+
NAME VARCHAR(30)
4851
);
4952
CREATE TABLE MANUAL
5053
(
51-
"id2" BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
54+
"id2" BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
5255
LEGO_SET BIGINT,
5356
"alternative" BIGINT,
5457
CONTENT VARCHAR(2000)
@@ -358,11 +361,26 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
358361

359362
CREATE TABLE WITH_ID_ONLY
360363
(
361-
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY
364+
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY
362365
);
363366

364367
CREATE TABLE WITH_INSERT_ONLY
365368
(
366-
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
367-
INSERT_ONLY VARCHAR(100)
368-
);
369+
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
370+
INSERT_ONLY VARCHAR(100)
371+
);
372+
373+
CREATE TABLE MAP_ELEMENT
374+
(
375+
MULTIPLE_COLLECTIONS BIGINT,
376+
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
377+
ENUM_MAP_OWNER BIGINT,
378+
ENUM_MAP_OWNER_KEY VARCHAR(10),
379+
NAME VARCHAR(100)
380+
);
381+
382+
CREATE TABLE ENUM_MAP_OWNER
383+
(
384+
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
385+
NAME VARCHAR(100)
386+
);

spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,21 @@ CREATE TABLE WITH_ID_ONLY
330330

331331
CREATE TABLE WITH_INSERT_ONLY
332332
(
333-
ID SERIAL PRIMARY KEY,
333+
ID SERIAL PRIMARY KEY,
334334
INSERT_ONLY VARCHAR(100)
335-
);
335+
);
336+
337+
CREATE TABLE MAP_ELEMENT
338+
(
339+
MULTIPLE_COLLECTIONS BIGINT,
340+
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
341+
ENUM_MAP_OWNER BIGINT,
342+
ENUM_MAP_OWNER_KEY VARCHAR(10),
343+
NAME VARCHAR(100)
344+
);
345+
346+
CREATE TABLE ENUM_MAP_OWNER
347+
(
348+
ID SERIAL PRIMARY KEY,
349+
NAME VARCHAR(100)
350+
);

spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,26 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
327327

328328
CREATE TABLE WITH_INSERT_ONLY
329329
(
330-
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
330+
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
331331
INSERT_ONLY VARCHAR(100)
332332
);
333333

334334
CREATE TABLE WITH_ID_ONLY
335335
(
336336
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY
337-
)
337+
);
338+
339+
CREATE TABLE MAP_ELEMENT
340+
(
341+
MULTIPLE_COLLECTIONS BIGINT,
342+
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
343+
ENUM_MAP_OWNER BIGINT,
344+
ENUM_MAP_OWNER_KEY VARCHAR(10),
345+
NAME VARCHAR(100)
346+
);
347+
348+
CREATE TABLE ENUM_MAP_OWNER
349+
(
350+
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
351+
NAME VARCHAR(100)
352+
);

spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mariadb.sql

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,26 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
300300

301301
CREATE TABLE WITH_ID_ONLY
302302
(
303-
ID BIGINT AUTO_INCREMENT PRIMARY KEY
303+
ID BIGINT AUTO_INCREMENT PRIMARY KEY
304304
);
305305

306306
CREATE TABLE WITH_INSERT_ONLY
307307
(
308-
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
309-
INSERT_ONLY VARCHAR(100)
310-
);
308+
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
309+
INSERT_ONLY VARCHAR(100)
310+
);
311+
312+
CREATE TABLE MAP_ELEMENT
313+
(
314+
MULTIPLE_COLLECTIONS BIGINT,
315+
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
316+
ENUM_MAP_OWNER BIGINT,
317+
ENUM_MAP_OWNER_KEY VARCHAR(10),
318+
NAME VARCHAR(100)
319+
);
320+
321+
CREATE TABLE ENUM_MAP_OWNER
322+
(
323+
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
324+
NAME VARCHAR(100)
325+
);

spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mssql.sql

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,23 @@ DROP TABLE IF EXISTS WITH_INSERT_ONLY;
337337

338338
CREATE TABLE WITH_INSERT_ONLY
339339
(
340-
ID BIGINT IDENTITY PRIMARY KEY,
341-
INSERT_ONLY VARCHAR(100)
342-
);
340+
ID BIGINT IDENTITY PRIMARY KEY,
341+
INSERT_ONLY VARCHAR(100)
342+
);
343+
344+
DROP TABLE MAP_ELEMENT;
345+
CREATE TABLE MAP_ELEMENT
346+
(
347+
MULTIPLE_COLLECTIONS BIGINT,
348+
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
349+
ENUM_MAP_OWNER BIGINT,
350+
ENUM_MAP_OWNER_KEY VARCHAR(10),
351+
NAME VARCHAR(100)
352+
);
353+
354+
DROP TABLE ENUM_MAP_OWNER;
355+
CREATE TABLE ENUM_MAP_OWNER
356+
(
357+
ID BIGINT IDENTITY PRIMARY KEY,
358+
NAME VARCHAR(100)
359+
);

spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mysql.sql

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,26 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
305305

306306
CREATE TABLE WITH_ID_ONLY
307307
(
308-
ID BIGINT AUTO_INCREMENT PRIMARY KEY
308+
ID BIGINT AUTO_INCREMENT PRIMARY KEY
309309
);
310310

311311
CREATE TABLE WITH_INSERT_ONLY
312312
(
313-
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
314-
INSERT_ONLY VARCHAR(100)
315-
);
313+
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
314+
INSERT_ONLY VARCHAR(100)
315+
);
316+
317+
CREATE TABLE MAP_ELEMENT
318+
(
319+
MULTIPLE_COLLECTIONS BIGINT,
320+
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
321+
ENUM_MAP_OWNER BIGINT,
322+
ENUM_MAP_OWNER_KEY VARCHAR(10),
323+
NAME VARCHAR(100)
324+
);
325+
326+
CREATE TABLE ENUM_MAP_OWNER
327+
(
328+
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
329+
NAME VARCHAR(100)
330+
);

spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-oracle.sql

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@ DROP TABLE WITH_LOCAL_DATE_TIME CASCADE CONSTRAINTS PURGE;
3131
DROP TABLE WITH_ID_ONLY CASCADE CONSTRAINTS PURGE;
3232
DROP TABLE WITH_INSERT_ONLY CASCADE CONSTRAINTS PURGE;
3333

34+
DROP TABLE MAP_ELEMENT CASCADE CONSTRAINTS PURGE;
35+
DROP TABLE ENUM_MAP_OWNER CASCADE CONSTRAINTS PURGE;
36+
3437
CREATE TABLE LEGO_SET
3538
(
3639
"id1" NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY,
37-
NAME VARCHAR(30)
40+
NAME VARCHAR(30)
3841
);
3942
CREATE TABLE MANUAL
4043
(
41-
"id2" NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY,
44+
"id2" NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY,
4245
LEGO_SET NUMBER,
4346
ALTERNATIVE NUMBER,
4447
CONTENT VARCHAR(2000)
@@ -338,12 +341,27 @@ CREATE TABLE WITH_LOCAL_DATE_TIME
338341

339342
CREATE TABLE WITH_ID_ONLY
340343
(
341-
ID NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY
344+
ID NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY
342345
);
343346

344347

345348
CREATE TABLE WITH_INSERT_ONLY
346349
(
347-
ID NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY,
348-
INSERT_ONLY VARCHAR(100)
349-
);
350+
ID NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY,
351+
INSERT_ONLY VARCHAR(100)
352+
);
353+
354+
CREATE TABLE MAP_ELEMENT
355+
(
356+
MULTIPLE_COLLECTIONS NUMBER,
357+
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
358+
ENUM_MAP_OWNER BIGINT,
359+
ENUM_MAP_OWNER_KEY VARCHAR(10),
360+
NAME VARCHAR(100)
361+
);
362+
363+
CREATE TABLE ENUM_MAP_OWNER
364+
(
365+
ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
366+
NAME VARCHAR(100)
367+
);

0 commit comments

Comments
 (0)