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
This commit is contained in:
Jens Schauder
2024-04-16 16:54:48 +02:00
parent 1a9701859e
commit 30e4ddd2e6
10 changed files with 71 additions and 33 deletions

View File

@@ -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;
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
if (property.isCollectionLike() || property.isMap()) {
Identifier identifierToUse = this.identifier;
AggregatePath idDefiningParentPath = aggregatePath.getIdDefiningParentPath();
if (property.getOwner().hasIdProperty()) {
// 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()) {
Object id = this.identifier.get(property.getOwner().getRequiredIdProperty().getColumnName());
Class<?> idType = idDefiningParentPath.getRequiredIdProperty().getActualType();
SqlIdentifier parentId = idDefiningParentPath.getTableInfo().idColumnName();
Object idValue = this.identifier.get(parentId);
if (id != null) {
identifierToUse = Identifier.of(aggregatePath.getTableInfo().reverseColumnInfo().name(), id,
Object.class);
}
Assert.state(idValue != null, "idValue must not be null at this point");
identifierToUse = Identifier.of(aggregatePath.getTableInfo().reverseColumnInfo().name(), idValue, idType);
}
Iterable<Object> allByPath = relationResolver.findAllByPath(identifierToUse,