Browse Source

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
3.1.x
Jens Schauder 2 years ago committed by Mark Paluch
parent
commit
b063663d24
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 2
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/JdbcAggregateChangeExecutionContext.java
  2. 9
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MapEntityRowMapper.java
  3. 16
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java
  4. 18
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-db2.sql
  5. 15
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-h2.sql
  6. 17
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-hsql.sql
  7. 15
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mariadb.sql
  8. 17
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mssql.sql
  9. 15
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-mysql.sql
  10. 18
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-oracle.sql
  11. 18
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.core/JdbcAggregateTemplateIntegrationTests-postgres.sql

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

@ -245,7 +245,7 @@ class JdbcAggregateChangeExecutionContext { @@ -245,7 +245,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;
}

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

@ -23,7 +23,9 @@ import java.util.Map; @@ -23,7 +23,9 @@ import java.util.Map;
import org.springframework.data.relational.core.mapping.PersistentPropertyPathExtension;
import org.springframework.data.relational.core.sql.IdentifierProcessing;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.data.util.TypeInformation;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;
/**
* 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>> { @@ -50,8 +52,11 @@ 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));
Object key = new ResultSetAccessor(rs).getObject(keyColumn.getReference());
Class<?> qualifierColumnType = path.getRequiredPersistentPropertyPath().getLeafProperty().getQualifierColumnType();
Object convertedKey = converter.readValue(key, TypeInformation.of(qualifierColumnType));
return new HashMap.SimpleEntry<>(convertedKey, mapEntity(rs, key));
}
private T mapEntity(ResultSet resultSet, Object key) {

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

@ -1095,6 +1095,16 @@ class JdbcAggregateTemplateIntegrationTests { @@ -1095,6 +1095,16 @@ class JdbcAggregateTemplateIntegrationTests {
assertThat(template.findById(entity.id, EnumArrayOwner.class).digits).isEqualTo(new Color[]{Color.BLUE});
}
@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);
@ -1548,6 +1558,12 @@ class JdbcAggregateTemplateIntegrationTests { @@ -1548,6 +1558,12 @@ class JdbcAggregateTemplateIntegrationTests {
String insertOnly;
}
record EnumMapOwner(@Id Long id, String name, Map<Color, MapElement> map) {
}
record MapElement(String name) {
}
@Configuration
@Import(TestConfiguration.class)
static class Config {

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

@ -41,6 +41,9 @@ DROP TABLE WITH_ID_ONLY; @@ -41,6 +41,9 @@ DROP TABLE WITH_ID_ONLY;
DROP TABLE WITH_INSERT_ONLY;
DROP TABLE MAP_ELEMENT;
DROP TABLE ENUM_MAP_OWNER;
CREATE TABLE LEGO_SET
(
"id1" BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
@ -366,3 +369,18 @@ CREATE TABLE WITH_INSERT_ONLY @@ -366,3 +369,18 @@ CREATE TABLE WITH_INSERT_ONLY
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
INSERT_ONLY VARCHAR(100)
);
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)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
NAME VARCHAR(100)
);

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

@ -333,3 +333,18 @@ CREATE TABLE WITH_INSERT_ONLY @@ -333,3 +333,18 @@ CREATE TABLE WITH_INSERT_ONLY
ID SERIAL PRIMARY KEY,
INSERT_ONLY VARCHAR(100)
);
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)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID SERIAL PRIMARY KEY,
NAME VARCHAR(100)
);

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

@ -334,4 +334,19 @@ CREATE TABLE WITH_INSERT_ONLY @@ -334,4 +334,19 @@ CREATE TABLE WITH_INSERT_ONLY
CREATE TABLE WITH_ID_ONLY
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY
)
);
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)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
NAME VARCHAR(100)
);

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

@ -308,3 +308,18 @@ CREATE TABLE WITH_INSERT_ONLY @@ -308,3 +308,18 @@ CREATE TABLE WITH_INSERT_ONLY
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
INSERT_ONLY VARCHAR(100)
);
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)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(100)
);

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

@ -340,3 +340,20 @@ CREATE TABLE WITH_INSERT_ONLY @@ -340,3 +340,20 @@ CREATE TABLE WITH_INSERT_ONLY
ID BIGINT IDENTITY PRIMARY KEY,
INSERT_ONLY VARCHAR(100)
);
DROP TABLE MAP_ELEMENT;
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)
);
DROP TABLE ENUM_MAP_OWNER;
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT IDENTITY PRIMARY KEY,
NAME VARCHAR(100)
);

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

@ -313,3 +313,18 @@ CREATE TABLE WITH_INSERT_ONLY @@ -313,3 +313,18 @@ CREATE TABLE WITH_INSERT_ONLY
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
INSERT_ONLY VARCHAR(100)
);
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)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT AUTO_INCREMENT PRIMARY KEY,
NAME VARCHAR(100)
);

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

@ -31,6 +31,9 @@ DROP TABLE WITH_LOCAL_DATE_TIME CASCADE CONSTRAINTS PURGE; @@ -31,6 +31,9 @@ DROP TABLE WITH_LOCAL_DATE_TIME CASCADE CONSTRAINTS PURGE;
DROP TABLE WITH_ID_ONLY CASCADE CONSTRAINTS PURGE;
DROP TABLE WITH_INSERT_ONLY CASCADE CONSTRAINTS PURGE;
DROP TABLE MAP_ELEMENT 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,
@ -347,3 +350,18 @@ CREATE TABLE WITH_INSERT_ONLY @@ -347,3 +350,18 @@ CREATE TABLE WITH_INSERT_ONLY
ID NUMBER GENERATED by default on null as IDENTITY PRIMARY KEY,
INSERT_ONLY VARCHAR(100)
);
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)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
NAME VARCHAR(100)
);

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

@ -15,6 +15,9 @@ DROP TABLE WITH_READ_ONLY; @@ -15,6 +15,9 @@ DROP TABLE WITH_READ_ONLY;
DROP TABLE WITH_ID_ONLY;
DROP TABLE WITH_INSERT_ONLY;
DROP TABLE MAP_ELEMENT;
DROP TABLE ENUM_MAP_OWNER;
CREATE TABLE LEGO_SET
(
"id1" SERIAL PRIMARY KEY,
@ -349,3 +352,18 @@ CREATE TABLE WITH_INSERT_ONLY @@ -349,3 +352,18 @@ CREATE TABLE WITH_INSERT_ONLY
ID SERIAL PRIMARY KEY,
INSERT_ONLY VARCHAR(100)
);
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)
);
CREATE TABLE ENUM_MAP_OWNER
(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
NAME VARCHAR(100)
);

Loading…
Cancel
Save