From 757227890aba62d3c6e0001cf53410fd63aee6a7 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 7 Feb 2024 11:45:16 +0100 Subject: [PATCH 1/2] Prepare issue branch. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8576363d34..dc9cdf4353 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-commons - 3.3.0-SNAPSHOT + 3.3.x-3038-SNAPSHOT Spring Data Core Core Spring concepts underpinning every Spring Data module. From 52870af9332185f177517daf2422c908f296120f Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 7 Feb 2024 12:32:43 +0100 Subject: [PATCH 2/2] Type parameter of static inner should not be considered enclosigClassParameter. --- .../data/mapping/Parameter.java | 4 +- .../data/mapping/ParameterUnitTests.java | 85 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/mapping/Parameter.java b/src/main/java/org/springframework/data/mapping/Parameter.java index 091370cd52..14d53a6cfb 100644 --- a/src/main/java/org/springframework/data/mapping/Parameter.java +++ b/src/main/java/org/springframework/data/mapping/Parameter.java @@ -24,6 +24,7 @@ import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** @@ -31,6 +32,7 @@ * * @param the type of the parameter * @author Oliver Gierke + * @author Christoph Strobl */ public class Parameter> { @@ -72,7 +74,7 @@ public Parameter(@Nullable String name, TypeInformation type, Annotation[] an } Class owningType = entity.getType(); - return owningType.isMemberClass() && type.getType().equals(owningType.getEnclosingClass()); + return ClassUtils.isInnerClass(owningType) && type.getType().equals(owningType.getEnclosingClass()); }); this.hasSpelExpression = Lazy.of(() -> StringUtils.hasText(getSpelExpression())); diff --git a/src/test/java/org/springframework/data/mapping/ParameterUnitTests.java b/src/test/java/org/springframework/data/mapping/ParameterUnitTests.java index eb0b4c67ac..3465c8f045 100755 --- a/src/test/java/org/springframework/data/mapping/ParameterUnitTests.java +++ b/src/test/java/org/springframework/data/mapping/ParameterUnitTests.java @@ -16,19 +16,27 @@ package org.springframework.data.mapping; import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; import java.lang.annotation.Annotation; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.mapping.ParameterUnitTests.IFace.ClassMember; +import org.springframework.data.mapping.ParameterUnitTests.IFace.RecordMember; +import org.springframework.data.mapping.ParameterUnitTests.StaticType.NonStaticInner; +import org.springframework.data.mapping.ParameterUnitTests.StaticType.RecordInner; +import org.springframework.data.mapping.ParameterUnitTests.StaticType.StaticInner; import org.springframework.data.util.TypeInformation; /** * Unit tests for {@link Parameter}. * * @author Oliver Gierke + * @author Christoph Strobl */ @ExtendWith(MockitoExtension.class) class ParameterUnitTests

> { @@ -87,4 +95,81 @@ void twoParametersWithDifferenTypeAreNotEqual() { assertThat(left).isNotEqualTo(right); } + + @Test // GH-3038 + void shouldNotConsiderRecordTypeOfInterfaceEnclosingClassParameter() { + + PersistentEntity pe = Mockito.mock(PersistentEntity.class); + when(pe.getType()).thenReturn(RecordMember.class); + + Parameter iFace = new Parameter("iFace", TypeInformation.of(IFace.class), annotations, pe); + assertThat(iFace.isEnclosingClassParameter()).isFalse(); + } + + @Test // GH-3038 + void shouldNotConsiderMemberTypeOfInterfaceEnclosingClassParameter() { + + PersistentEntity pe = Mockito.mock(PersistentEntity.class); + when(pe.getType()).thenReturn(ClassMember.class); + + Parameter iFace = new Parameter("iFace", TypeInformation.of(IFace.class), annotations, pe); + assertThat(iFace.isEnclosingClassParameter()).isFalse(); + } + + @Test // GH-3038 + void shouldConsiderMemberTypeOfClassEnclosingClassParameter() { + + PersistentEntity pe = Mockito.mock(PersistentEntity.class); + when(pe.getType()).thenReturn(NonStaticInner.class); + + Parameter iFace = new Parameter("outer", TypeInformation.of(StaticType.class), + annotations, pe); + assertThat(iFace.isEnclosingClassParameter()).isTrue(); + } + + @Test // GH-3038 + void shouldNotConsiderStaticMemberTypeOfClassEnclosingClassParameter() { + + PersistentEntity pe = Mockito.mock(PersistentEntity.class); + when(pe.getType()).thenReturn(StaticInner.class); + + Parameter iFace = new Parameter("outer", TypeInformation.of(StaticType.class), + annotations, pe); + assertThat(iFace.isEnclosingClassParameter()).isFalse(); + } + + @Test // GH-3038 + void shouldNotConsiderRecordMemberTypeOfClassEnclosingClassParameter() { + + PersistentEntity pe = Mockito.mock(PersistentEntity.class); + when(pe.getType()).thenReturn(RecordInner.class); + + Parameter iFace = new Parameter("outer", TypeInformation.of(StaticType.class), + annotations, pe); + assertThat(iFace.isEnclosingClassParameter()).isFalse(); + } + + interface IFace { + + record RecordMember(IFace iFace) { + } + + class ClassMember { + ClassMember(IFace iface) {} + } + } + + static class StaticType { + + class NonStaticInner { + NonStaticInner(StaticType outer) {} + } + + static class StaticInner { + StaticInner(StaticType outer) {} + } + + record RecordInner(StaticType outer) { + } + } }