From eae39d443834b6258346a0e51c0386960462fe84 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Mon, 13 Nov 2023 09:51:12 +0100 Subject: [PATCH] `AggregatePath` caching considers property owner. Since a PersistencePropertyPath does NOT consider it's owner for equality, this is necessary. to distinguish different AggregatePath instances based on a inherited property. Closes #1657 Original pull request: #1661 --- .../core/mapping/DefaultAggregatePath.java | 2 +- .../mapping/RelationalMappingContext.java | 23 +++++++++++++++---- .../RelationalMappingContextUnitTests.java | 22 ++++++++++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DefaultAggregatePath.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DefaultAggregatePath.java index 015857e9..0c397562 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DefaultAggregatePath.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/DefaultAggregatePath.java @@ -52,7 +52,7 @@ class DefaultAggregatePath implements AggregatePath { this.context = context; this.path = (PersistentPropertyPath) path; - this.rootType = null; + this.rootType = path.getBaseProperty().getOwner(); } DefaultAggregatePath(RelationalMappingContext context, RelationalPersistentEntity rootType) { diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java index ac453b4a..10c66cdc 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/mapping/RelationalMappingContext.java @@ -186,11 +186,13 @@ public class RelationalMappingContext */ public AggregatePath getAggregatePath(PersistentPropertyPath path) { - AggregatePath aggregatePath = aggregatePathCache.get(path); + AggregatePathCacheKey cacheKey = AggregatePathCacheKey.of(path); + + AggregatePath aggregatePath = aggregatePathCache.get(cacheKey); if (aggregatePath == null) { aggregatePath = new DefaultAggregatePath(this, path); - aggregatePathCache.put(path, aggregatePath); + aggregatePathCache.put(cacheKey, aggregatePath); } return aggregatePath; @@ -198,13 +200,26 @@ public class RelationalMappingContext public AggregatePath getAggregatePath(RelationalPersistentEntity type) { - AggregatePath aggregatePath = aggregatePathCache.get(type); + AggregatePathCacheKey cacheKey = AggregatePathCacheKey.of(type); + + AggregatePath aggregatePath = aggregatePathCache.get(cacheKey); if (aggregatePath == null) { aggregatePath = new DefaultAggregatePath(this, type); - aggregatePathCache.put(type, aggregatePath); + aggregatePathCache.put(cacheKey, aggregatePath); } return aggregatePath; } + + private record AggregatePathCacheKey(RelationalPersistentEntity root,@Nullable PersistentPropertyPath path) { + static AggregatePathCacheKey of(RelationalPersistentEntity root) { + return new AggregatePathCacheKey(root, null); + } + static AggregatePathCacheKey of(PersistentPropertyPath path) { + + RelationalPersistentEntity root = path.getBaseProperty().getOwner(); + return new AggregatePathCacheKey(root, path); + } + } } diff --git a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalMappingContextUnitTests.java b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalMappingContextUnitTests.java index c0377fdc..ee7e3ce2 100644 --- a/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalMappingContextUnitTests.java +++ b/spring-data-relational/src/test/java/org/springframework/data/relational/core/mapping/RelationalMappingContextUnitTests.java @@ -104,6 +104,20 @@ public class RelationalMappingContextUnitTests { assertThat(name.getColumnName()).isEqualTo(SqlIdentifier.quoted("PRNT_CHLD_NAME")); } + @Test // GH-1657 + void aggregatePathsOfBasePropertyForDifferentInheritedEntitiesAreDifferent() { + + PersistentPropertyPath path1 = context.getPersistentPropertyPath("name", + Inherit1.class); + PersistentPropertyPath path2 = context.getPersistentPropertyPath("name", + Inherit2.class); + + AggregatePath aggregatePath1 = context.getAggregatePath(path1); + AggregatePath aggregatePath2 = context.getAggregatePath(path2); + + assertThat(aggregatePath1).isNotEqualTo(aggregatePath2); + } + static class EntityWithUuid { @Id UUID uuid; } @@ -121,4 +135,12 @@ public class RelationalMappingContextUnitTests { String name; } + static class Base { + String name; + } + + static class Inherit1 extends Base {} + + static class Inherit2 extends Base {} + }