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
This commit is contained in:
Jens Schauder
2023-11-15 09:32:38 +01:00
committed by Mark Paluch
parent f2da860a99
commit 15bb8d1eef
11 changed files with 96 additions and 6 deletions

View File

@@ -241,7 +241,7 @@ class JdbcAggregateChangeExecutionContext {
RelationalPersistentEntity<?> persistentEntity = getRequiredPersistentEntity(idOwningAction.getEntityType());
Object identifier = persistentEntity.getIdentifierAccessor(idOwningAction.getEntity()).getIdentifier();
Assert.state(identifier != null, "Couldn't obtain a required id value");
Assert.state(identifier != null,() -> "Couldn't obtain a required id value for " + persistentEntity);
return identifier;
}

View File

@@ -23,6 +23,7 @@ import java.util.Map;
import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.data.relational.domain.RowDocument;
import org.springframework.data.util.TypeInformation;
import org.springframework.jdbc.core.RowMapper;
/**
@@ -51,15 +52,19 @@ class MapEntityRowMapper<T> implements RowMapper<Map.Entry<Object, T>> {
@Override
public Map.Entry<Object, T> mapRow(ResultSet rs, int rowNum) throws SQLException {
Object key = rs.getObject(keyColumn.getReference());
return new HashMap.SimpleEntry<>(key, mapEntity(rs, key));
RowDocument document = RowDocumentResultSetExtractor.toRowDocument(rs);
Object key = document.get(keyColumn.getReference());
Class<?> qualifierColumnType = path.getRequiredLeafProperty().getQualifierColumnType();
Object convertedKey = converter.readValue(key, TypeInformation.of(qualifierColumnType));
return new HashMap.SimpleEntry<>(convertedKey, mapEntity(document, key));
}
@SuppressWarnings("unchecked")
private T mapEntity(ResultSet resultSet, Object key) throws SQLException {
private T mapEntity(RowDocument document, Object key) {
RowDocument document = RowDocumentResultSetExtractor.toRowDocument(resultSet);
return (T) converter.readAndResolve(path.getLeafEntity().getType(), document,
return (T) converter.readAndResolve(path.getRequiredLeafEntity().getType(), document,
identifier.withPart(keyColumn, key, Object.class));
}
}

View File

@@ -1278,6 +1278,16 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
assertThat(authors).containsExactly(tolkien);
}
@Test // GH-1656
void mapWithEnumKey() {
EnumMapOwner enumMapOwner = template.save(new EnumMapOwner(null, "OwnerName", Map.of(Color.BLUE, new MapElement("Element"))));
Iterable<EnumMapOwner> enumMapOwners = template.findAll(EnumMapOwner.class);
assertThat(enumMapOwners).containsExactly(enumMapOwner);
}
private <T extends Number> void saveAndUpdateAggregateWithVersion(VersionedAggregate aggregate,
Function<Number, T> toConcreteNumber) {
saveAndUpdateAggregateWithVersion(aggregate, toConcreteNumber, 0);
@@ -2096,6 +2106,10 @@ abstract class AbstractJdbcAggregateTemplateIntegrationTests {
}
record EnumMapOwner(@Id Long id, String name, Map<Color, MapElement> map) {
}
@Configuration
@Import(TestConfiguration.class)
static class Config {

View File

@@ -50,6 +50,8 @@ DROP TABLE SET_ELEMENT;
DROP TABLE BOOK;
DROP TABLE AUTHOR;
DROP TABLE ENUM_MAP_OWNER;
CREATE TABLE LEGO_SET
(
"id1" BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
@@ -406,6 +408,8 @@ CREATE TABLE MAP_ELEMENT
(
MULTIPLE_COLLECTIONS BIGINT,
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
ENUM_MAP_OWNER BIGINT,
ENUM_MAP_OWNER_KEY VARCHAR(10),
NAME VARCHAR(100)
);
@@ -419,3 +423,9 @@ CREATE TABLE BOOK
AUTHOR BIGINT,
NAME VARCHAR(100)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
NAME VARCHAR(100)
);

View File

@@ -365,6 +365,8 @@ CREATE TABLE MAP_ELEMENT
(
MULTIPLE_COLLECTIONS BIGINT,
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
ENUM_MAP_OWNER BIGINT,
ENUM_MAP_OWNER_KEY VARCHAR(10),
NAME VARCHAR(100)
);
@@ -378,3 +380,9 @@ CREATE TABLE BOOK
AUTHOR BIGINT,
NAME VARCHAR(100)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID SERIAL PRIMARY KEY,
NAME VARCHAR(100)
);

View File

@@ -366,6 +366,8 @@ CREATE TABLE MAP_ELEMENT
(
MULTIPLE_COLLECTIONS BIGINT,
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
ENUM_MAP_OWNER BIGINT,
ENUM_MAP_OWNER_KEY VARCHAR(10),
NAME VARCHAR(100)
);
@@ -379,3 +381,9 @@ CREATE TABLE BOOK
AUTHOR BIGINT,
NAME VARCHAR(100)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
NAME VARCHAR(100)
);

View File

@@ -339,6 +339,8 @@ CREATE TABLE MAP_ELEMENT
(
MULTIPLE_COLLECTIONS BIGINT,
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
ENUM_MAP_OWNER BIGINT,
ENUM_MAP_OWNER_KEY VARCHAR(10),
NAME VARCHAR(100)
);
@@ -352,3 +354,9 @@ CREATE TABLE BOOK
AUTHOR BIGINT,
NAME VARCHAR(100)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(100)
);

View File

@@ -377,6 +377,8 @@ CREATE TABLE MAP_ELEMENT
(
MULTIPLE_COLLECTIONS BIGINT,
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
ENUM_MAP_OWNER BIGINT,
ENUM_MAP_OWNER_KEY VARCHAR(10),
NAME VARCHAR(100)
);
@@ -393,3 +395,10 @@ CREATE TABLE BOOK
AUTHOR BIGINT,
NAME VARCHAR(100)
);
DROP TABLE ENUM_MAP_OWNER;
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT IDENTITY PRIMARY KEY,
NAME VARCHAR(100)
);

View File

@@ -344,6 +344,8 @@ CREATE TABLE MAP_ELEMENT
(
MULTIPLE_COLLECTIONS BIGINT,
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
ENUM_MAP_OWNER BIGINT,
ENUM_MAP_OWNER_KEY VARCHAR(10),
NAME VARCHAR(100)
);
@@ -357,3 +359,9 @@ CREATE TABLE BOOK
AUTHOR BIGINT,
NAME VARCHAR(100)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(100)
);

View File

@@ -40,6 +40,8 @@ DROP TABLE SET_ELEMENT CASCADE CONSTRAINTS PURGE;
DROP TABLE BOOK CASCADE CONSTRAINTS PURGE;
DROP TABLE AUTHOR CASCADE CONSTRAINTS PURGE;
DROP TABLE ENUM_MAP_OWNER CASCADE CONSTRAINTS PURGE;
CREATE TABLE LEGO_SET
(
"id1" NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY,
@@ -387,6 +389,8 @@ CREATE TABLE MAP_ELEMENT
(
MULTIPLE_COLLECTIONS NUMBER,
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
ENUM_MAP_OWNER BIGINT,
ENUM_MAP_OWNER_KEY VARCHAR(10),
NAME VARCHAR(100)
);
@@ -400,3 +404,9 @@ CREATE TABLE BOOK
AUTHOR NUMBER,
NAME VARCHAR(100)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
NAME VARCHAR(100)
);

View File

@@ -43,6 +43,8 @@ DROP TABLE SET_ELEMENT;
DROP TABLE BOOK;
DROP TABLE AUTHOR;
DROP TABLE ENUM_MAP_OWNER;
CREATE TABLE LEGO_SET
(
"id1" SERIAL PRIMARY KEY,
@@ -409,6 +411,8 @@ CREATE TABLE MAP_ELEMENT
(
MULTIPLE_COLLECTIONS BIGINT,
MULTIPLE_COLLECTIONS_KEY VARCHAR(10),
ENUM_MAP_OWNER BIGINT,
ENUM_MAP_OWNER_KEY VARCHAR(10),
NAME VARCHAR(100)
);
@@ -422,3 +426,9 @@ CREATE TABLE BOOK
AUTHOR BIGINT,
NAME VARCHAR(100)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
NAME VARCHAR(100)
);