From 1545e184ef581d39fc538f582bae93fedde2aadf Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 27 Jun 2024 09:30:38 +0200 Subject: [PATCH] Apply unwrapped persistent property equality check to delegate. We now compare the other object whether it equals the delegate in case UnwrappedMongoPersistentProperty.equals is being called with the MongoPersistentProperty retrieved from a MappingContext. This ensures that unwrapped properties can be compared to vanilla MongoPersistentProperty instances when checking constructor/creator method correlation of parameters. Closes #4732 --- .../UnwrappedMongoPersistentProperty.java | 4 +++ .../AuditingEntityCallbackUnitTests.java | 31 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java index 3e4581c8a..ef6babe97 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java @@ -362,6 +362,10 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty { return true; } + if (obj == delegate) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { return false; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AuditingEntityCallbackUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AuditingEntityCallbackUnitTests.java index 4e2d26777..4223d9866 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AuditingEntityCallbackUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/event/AuditingEntityCallbackUnitTests.java @@ -34,6 +34,7 @@ import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.auditing.IsNewAwareAuditingHandler; import org.springframework.data.mapping.context.PersistentEntities; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; +import org.springframework.data.mongodb.core.mapping.Unwrapped; /** * Unit tests for {@link AuditingEntityCallback}. @@ -43,13 +44,14 @@ import org.springframework.data.mongodb.core.mapping.MongoMappingContext; @ExtendWith(MockitoExtension.class) public class AuditingEntityCallbackUnitTests { + private final MongoMappingContext mappingContext = new MongoMappingContext(); + private IsNewAwareAuditingHandler handler; private AuditingEntityCallback callback; @BeforeEach void setUp() { - MongoMappingContext mappingContext = new MongoMappingContext(); mappingContext.getPersistentEntity(Sample.class); handler = spy(new IsNewAwareAuditingHandler(new PersistentEntities(Arrays.asList(mappingContext)))); @@ -105,6 +107,21 @@ public class AuditingEntityCallbackUnitTests { assertThat(result).isSameAs(newSample); } + @Test // GH-4732 + void shouldApplyAuditingToUnwrappedImmutableObject() { + + WithUnwrapped sample = new WithUnwrapped(); + sample.auditingData = new MyAuditingData(null, null); + + IsNewAwareAuditingHandler handler = new IsNewAwareAuditingHandler(PersistentEntities.of(mappingContext)); + + AuditingEntityCallback listener = new AuditingEntityCallback(() -> handler); + WithUnwrapped result = (WithUnwrapped) listener.onBeforeConvert(sample, "foo"); + + assertThat(result.auditingData.created).isNotNull(); + assertThat(result.auditingData.modified).isNotNull(); + } + static class Sample { @Id String id; @@ -112,6 +129,18 @@ public class AuditingEntityCallbackUnitTests { @LastModifiedDate Date modified; } + static class WithUnwrapped { + + @Id String id; + + @Unwrapped(onEmpty = Unwrapped.OnEmpty.USE_NULL) MyAuditingData auditingData; + + } + + record MyAuditingData(@CreatedDate Date created, @LastModifiedDate Date modified) { + + } + private static final class ImmutableSample { @Id private final String id;