Browse Source

Fix loading of 2nd level collections.

Construction of the back reference assumed that the table holding the parent of the foreign key is the actual parent property.
This is now corrected by using the correct API to identify the ancestor which holds the id.

Closes: #1692
Original pull request: #1773
pull/1776/head
Jens Schauder 2 years ago
parent
commit
30e4ddd2e6
No known key found for this signature in database
GPG Key ID: 89F36EDF8C1BEA56
  1. 18
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/MappingJdbcConverter.java
  2. 11
      spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests.java
  3. 4
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-db2.sql
  4. 4
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-h2.sql
  5. 4
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-hsql.sql
  6. 15
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-mariadb.sql
  7. 15
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-mssql.sql
  8. 15
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-mysql.sql
  9. 14
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-oracle.sql
  10. 4
      spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-postgres.sql

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

@ -26,7 +26,6 @@ import java.util.function.Function; @@ -26,7 +26,6 @@ import java.util.function.Function;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.converter.Converter;
@ -45,6 +44,7 @@ import org.springframework.data.relational.core.mapping.AggregatePath; @@ -45,6 +44,7 @@ import org.springframework.data.relational.core.mapping.AggregatePath;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
import org.springframework.data.relational.core.sql.SqlIdentifier;
import org.springframework.data.relational.domain.RowDocument;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
@ -366,15 +366,19 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements @@ -366,15 +366,19 @@ public class MappingJdbcConverter extends MappingRelationalConverter implements
if (property.isCollectionLike() || property.isMap()) {
Identifier identifierToUse = this.identifier;
AggregatePath idDefiningParentPath = aggregatePath.getIdDefiningParentPath();
// note that the idDefiningParentPath might not itself have an id property, but have a combination of back
// references and possibly keys, that form an id
if (idDefiningParentPath.hasIdProperty()) {
if (property.getOwner().hasIdProperty()) {
Class<?> idType = idDefiningParentPath.getRequiredIdProperty().getActualType();
SqlIdentifier parentId = idDefiningParentPath.getTableInfo().idColumnName();
Object idValue = this.identifier.get(parentId);
Object id = this.identifier.get(property.getOwner().getRequiredIdProperty().getColumnName());
Assert.state(idValue != null, "idValue must not be null at this point");
if (id != null) {
identifierToUse = Identifier.of(aggregatePath.getTableInfo().reverseColumnInfo().name(), id,
Object.class);
}
identifierToUse = Identifier.of(aggregatePath.getTableInfo().reverseColumnInfo().name(), idValue, idType);
}
Iterable<Object> allByPath = relationResolver.findAllByPath(identifierToUse,

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

@ -69,13 +69,13 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests { @@ -69,13 +69,13 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
DummyEntity entity = repository.save(createDummyEntity());
assertThat(countRowsInTable("dummy_entity", entity.getId())).isEqualTo(1);
assertThat(countRowsInTable("dummy_entity2", entity.getId())).isEqualTo(2);
assertThat(countRowsInTable("dummy_entity", entity.getId(), "ID")).isEqualTo(1);
assertThat(countRowsInTable("dummy_entity2", entity.getId(), "DUMMY_ID")).isEqualTo(2);
}
private int countRowsInTable(String name, long idValue) {
private int countRowsInTable(String name, long idValue, String idColumnName) {
SqlIdentifier id = SqlIdentifier.quoted("ID");
SqlIdentifier id = SqlIdentifier.quoted(idColumnName);
String whereClause = id.toSql(dialect.getIdentifierProcessing()) + " = " + idValue;
return JdbcTestUtils.countRowsInTableWhere(template.getJdbcOperations(), name, whereClause);
@ -273,7 +273,8 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests { @@ -273,7 +273,8 @@ public class JdbcRepositoryEmbeddedWithCollectionIntegrationTests {
}
private static class Embeddable {
@MappedCollection(idColumn = "ID", keyColumn = "ORDER_KEY") List<DummyEntity2> list = new ArrayList<>();
@MappedCollection(idColumn = "DUMMY_ID", keyColumn = "ORDER_KEY")
List<DummyEntity2> list = new ArrayList<>();
String test;

4
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-db2.sql

@ -9,8 +9,8 @@ CREATE TABLE dummy_entity @@ -9,8 +9,8 @@ CREATE TABLE dummy_entity
);
CREATE TABLE dummy_entity2
(
id BIGINT NOT NULL,
dummy_id BIGINT NOT NULL,
ORDER_KEY BIGINT NOT NULL,
TEST VARCHAR(100),
PRIMARY KEY (id, ORDER_KEY)
PRIMARY KEY (dummy_id, ORDER_KEY)
)

4
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-h2.sql

@ -6,8 +6,8 @@ CREATE TABLE dummy_entity @@ -6,8 +6,8 @@ CREATE TABLE dummy_entity
);
CREATE TABLE dummy_entity2
(
id BIGINT,
dummy_id BIGINT,
ORDER_KEY BIGINT,
TEST VARCHAR(100),
PRIMARY KEY (id, ORDER_KEY)
PRIMARY KEY (dummy_id, ORDER_KEY)
)

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

@ -6,8 +6,8 @@ CREATE TABLE dummy_entity @@ -6,8 +6,8 @@ CREATE TABLE dummy_entity
);
CREATE TABLE dummy_entity2
(
id BIGINT,
dummy_id BIGINT,
ORDER_KEY BIGINT,
TEST VARCHAR(100),
PRIMARY KEY (id, ORDER_KEY)
PRIMARY KEY (dummy_id, ORDER_KEY)
)

15
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-mariadb.sql

@ -1,2 +1,13 @@ @@ -1,2 +1,13 @@
CREATE TABLE dummy_entity (id BIGINT AUTO_INCREMENT PRIMARY KEY, TEST VARCHAR(100), PREFIX_TEST VARCHAR(100));
CREATE TABLE dummy_entity2 (id BIGINT, ORDER_KEY BIGINT, TEST VARCHAR(100), PRIMARY KEY(id, ORDER_KEY));
CREATE TABLE dummy_entity
(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
TEST VARCHAR(100),
PREFIX_TEST VARCHAR(100)
);
CREATE TABLE dummy_entity2
(
dummy_id BIGINT,
ORDER_KEY BIGINT,
TEST VARCHAR(100),
PRIMARY KEY (dummy_id, ORDER_KEY)
);

15
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-mssql.sql

@ -1,4 +1,15 @@ @@ -1,4 +1,15 @@
DROP TABLE IF EXISTS dummy_entity;
CREATE TABLE dummy_entity (id BIGINT IDENTITY PRIMARY KEY, TEST VARCHAR(100), PREFIX_TEST VARCHAR(100));
CREATE TABLE dummy_entity
(
id BIGINT IDENTITY PRIMARY KEY,
TEST VARCHAR(100),
PREFIX_TEST VARCHAR(100)
);
DROP TABLE IF EXISTS dummy_entity2;
CREATE TABLE dummy_entity2 (id BIGINT, ORDER_KEY BIGINT, TEST VARCHAR(100), CONSTRAINT dummym_entity2_pk PRIMARY KEY(id, ORDER_KEY));
CREATE TABLE dummy_entity2
(
dummy_id BIGINT,
ORDER_KEY BIGINT,
TEST VARCHAR(100),
CONSTRAINT dummym_entity2_pk PRIMARY KEY (dummy_id, ORDER_KEY)
);

15
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-mysql.sql

@ -1,2 +1,13 @@ @@ -1,2 +1,13 @@
CREATE TABLE dummy_entity (id BIGINT AUTO_INCREMENT PRIMARY KEY, TEST VARCHAR(100), PREFIX_TEST VARCHAR(100));
CREATE TABLE dummy_entity2 (id BIGINT, ORDER_KEY BIGINT, TEST VARCHAR(100), PRIMARY KEY(id, ORDER_KEY));
CREATE TABLE dummy_entity
(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
TEST VARCHAR(100),
PREFIX_TEST VARCHAR(100)
);
CREATE TABLE dummy_entity2
(
dummy_id BIGINT,
ORDER_KEY BIGINT,
TEST VARCHAR(100),
PRIMARY KEY (dummy_id, ORDER_KEY)
);

14
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-oracle.sql

@ -3,15 +3,15 @@ DROP TABLE DUMMY_ENTITY CASCADE CONSTRAINTS PURGE; @@ -3,15 +3,15 @@ DROP TABLE DUMMY_ENTITY CASCADE CONSTRAINTS PURGE;
CREATE TABLE DUMMY_ENTITY
(
ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY,
TEST VARCHAR2(100),
PREFIX_TEST VARCHAR2(100)
ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY PRIMARY KEY,
TEST VARCHAR2(100),
PREFIX_TEST VARCHAR2(100)
);
CREATE TABLE DUMMY_ENTITY2
(
ID NUMBER,
ORDER_KEY NUMBER,
TEST VARCHAR2(100),
PRIMARY KEY (ID, ORDER_KEY)
DUMMY_ID NUMBER,
ORDER_KEY NUMBER,
TEST VARCHAR2(100),
PRIMARY KEY (DUMMY_ID, ORDER_KEY)
)

4
spring-data-jdbc/src/test/resources/org.springframework.data.jdbc.repository/JdbcRepositoryEmbeddedWithCollectionIntegrationTests-postgres.sql

@ -8,8 +8,8 @@ CREATE TABLE dummy_entity @@ -8,8 +8,8 @@ CREATE TABLE dummy_entity
DROP TABLE dummy_entity2;
CREATE TABLE dummy_entity2
(
"ID" BIGINT,
"DUMMY_ID" BIGINT,
"ORDER_KEY" BIGINT,
TEST VARCHAR(100),
PRIMARY KEY ("ID", "ORDER_KEY")
PRIMARY KEY ("DUMMY_ID", "ORDER_KEY")
);

Loading…
Cancel
Save