diff --git a/pom.xml b/pom.xml
index d0ddbb58ea..0d8867beb6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-commons
- 2.6.0-SNAPSHOT
+ 2.6.0-GH-2485-SNAPSHOT
Spring Data Core
diff --git a/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java b/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java
index a04306336c..83ed7b9d60 100644
--- a/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java
+++ b/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java
@@ -360,6 +360,17 @@ protected Optional addPersistentEntity(TypeInformation> typeInformation) {
return persistentEntity;
}
+ if(typeInformation.isProxyTypeInformation()) {
+
+ TypeInformation> userTypeInformation = typeInformation.getUserTypeInformation();
+ persistentEntity = persistentEntities.get(userTypeInformation);
+
+ if (persistentEntity != null) {
+ persistentEntities.put(typeInformation, persistentEntity);
+ return persistentEntity;
+ }
+ }
+
} finally {
read.unlock();
}
@@ -369,7 +380,10 @@ protected Optional addPersistentEntity(TypeInformation> typeInformation) {
try {
write.lock();
- entity = doAddPersistentEntity(typeInformation);
+ entity = doAddPersistentEntity(typeInformation.getUserTypeInformation());
+ if(typeInformation.isProxyTypeInformation()) {
+ persistentEntities.put(typeInformation, Optional.of(entity));
+ }
} catch (BeansException e) {
throw new MappingException(e.getMessage(), e);
diff --git a/src/main/java/org/springframework/data/util/ClassTypeInformation.java b/src/main/java/org/springframework/data/util/ClassTypeInformation.java
index 98e7132bc3..953b60feed 100644
--- a/src/main/java/org/springframework/data/util/ClassTypeInformation.java
+++ b/src/main/java/org/springframework/data/util/ClassTypeInformation.java
@@ -32,6 +32,7 @@
import org.springframework.util.Assert;
import org.springframework.util.ConcurrentReferenceHashMap;
import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType;
+import org.springframework.util.ObjectUtils;
/**
* {@link TypeInformation} for a plain {@link Class}.
@@ -177,4 +178,26 @@ public TypeInformation extends S> specialize(ClassTypeInformation> type) {
public String toString() {
return type.getName();
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!super.equals(o)) {
+ return false;
+ }
+
+ ClassTypeInformation> that = (ClassTypeInformation>) o;
+ return ObjectUtils.nullSafeEquals(type, that.type);
+ }
+
+ @Override
+ public int hashCode() {
+
+ int result = super.hashCode();
+ result = 31 * result + ObjectUtils.nullSafeHashCode(type);
+ return result;
+ }
}
diff --git a/src/main/java/org/springframework/data/util/TypeInformation.java b/src/main/java/org/springframework/data/util/TypeInformation.java
index d5a2f2642b..25615c6d96 100644
--- a/src/main/java/org/springframework/data/util/TypeInformation.java
+++ b/src/main/java/org/springframework/data/util/TypeInformation.java
@@ -149,6 +149,29 @@ default TypeInformation> getRequiredMapValueType() {
*/
Class getType();
+ /**
+ * Returns the user type of the property if proxied.
+ *
+ * @return the unpacked (if proxied) type of the property.
+ * @see ProxyUtils#getUserClass(Class)
+ * @since 2.6
+ */
+ default TypeInformation> getUserTypeInformation() {
+
+ Class> userType = ProxyUtils.getUserClass(getType());
+ return userType.equals(getType()) ? this : ClassTypeInformation.from(userType);
+ }
+
+ /**
+ * Returns if {@link #getType()} refers to a proxy or user class.
+ *
+ * @return true if type is a proxy.
+ * @since 2.6
+ */
+ default boolean isProxyTypeInformation() {
+ return !this.equals(getUserTypeInformation());
+ }
+
/**
* Returns a {@link ClassTypeInformation} to represent the {@link TypeInformation} of the raw type of the current
* instance.
diff --git a/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java b/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java
index f492abf816..ca79972f5d 100755
--- a/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java
+++ b/src/test/java/org/springframework/data/mapping/context/AbstractMappingContextUnitTests.java
@@ -37,8 +37,14 @@
import java.util.TreeMap;
import java.util.function.Supplier;
+import org.aopalliance.aop.Advice;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.springframework.aop.Advisor;
+import org.springframework.aop.SpringProxy;
+import org.springframework.aop.TargetSource;
+import org.springframework.aop.framework.Advised;
+import org.springframework.aop.framework.AopConfigException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
import org.springframework.data.annotation.Id;
@@ -54,6 +60,7 @@
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.StreamUtils;
import org.springframework.data.util.TypeInformation;
+import org.springframework.lang.Nullable;
/**
* Unit test for {@link AbstractMappingContext}.
@@ -323,6 +330,40 @@ void shouldNotCreatePersistentEntityForMapButItsGenericTypeArguments() {
.doesNotContain(List.class, Map.class, String.class, Integer.class);
}
+ @Test // GH-2485
+ void contextSeesUserTypeBeforeProxy() {
+
+ SampleMappingContext context = new SampleMappingContext();
+ BasicPersistentEntity