diff --git a/src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java b/src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java
index 2be9853779..ad0e0907ca 100644
--- a/src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java
+++ b/src/main/java/org/springframework/data/mapping/model/AnnotationBasedPersistentProperty.java
@@ -40,6 +40,7 @@
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.Lazy;
import org.springframework.data.util.Optionals;
+import org.springframework.data.util.ReflectionUtils;
import org.springframework.data.util.StreamUtils;
import org.springframework.data.util.TypeInformation;
import org.springframework.lang.Nullable;
@@ -56,6 +57,7 @@ public abstract class AnnotationBasedPersistentProperty
{
private static final String SPRING_DATA_PACKAGE = "org.springframework.data";
+ private static final Class extends Annotation> IDENTITY_TYPE = loadIdentityType();
private final @Nullable String value;
private final Map, Optional extends Annotation>> annotationCache = new ConcurrentHashMap<>();
@@ -74,7 +76,8 @@ public abstract class AnnotationBasedPersistentProperty !isTransient() && !isAnnotationPresent(ReadOnlyProperty.class));
private final Lazy isReference = Lazy.of(() -> !isTransient() //
&& (isAnnotationPresent(Reference.class) || super.isAssociation()));
- private final Lazy isId = Lazy.of(() -> isAnnotationPresent(Id.class));
+ private final Lazy isId = Lazy
+ .of(() -> isAnnotationPresent(Id.class) || IDENTITY_TYPE != null && isAnnotationPresent(IDENTITY_TYPE));
private final Lazy isVersion = Lazy.of(() -> isAnnotationPresent(Version.class));
private final Lazy> associationTargetType = Lazy.of(() -> {
@@ -329,4 +332,19 @@ private Stream extends AnnotatedElement> getAccessors() {
return Optionals.toStream(Optional.ofNullable(getGetter()), Optional.ofNullable(getSetter()),
Optional.ofNullable(getField()));
}
+
+ /**
+ * Load jMolecules' {@code @Identity} type if present on the classpath. Dedicated method instead of a simple static
+ * initializer to be able to suppress the compiler warning.
+ *
+ * @return can be {@literal null}.
+ */
+ @Nullable
+ @SuppressWarnings("unchecked")
+ private static Class extends Annotation> loadIdentityType() {
+
+ return (Class extends Annotation>) ReflectionUtils.loadIfPresent(
+ "org.jmolecules.ddd.annotation.Identity",
+ AbstractPersistentProperty.class.getClassLoader());
+ }
}
diff --git a/src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java
index 7b4a52a677..913a2e73d1 100755
--- a/src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java
+++ b/src/test/java/org/springframework/data/mapping/model/AnnotationBasedPersistentPropertyUnitTests.java
@@ -28,6 +28,7 @@
import java.util.stream.Stream;
import org.assertj.core.api.ClassAssert;
+import org.jmolecules.ddd.annotation.Identity;
import org.jmolecules.ddd.types.AggregateRoot;
import org.jmolecules.ddd.types.Association;
import org.jmolecules.ddd.types.Identifier;
@@ -329,6 +330,14 @@ void exposesAssociationTargetClassAsPersistentEntityType() {
.allMatch(it -> it.equals(ClassTypeInformation.from(Sample.class)));
}
+ @Test // #2438
+ void detectsJMoleculesIdentity() {
+
+ SamplePersistentProperty property = getProperty(JMolecules.class, "identifier");
+
+ assertThat(property.isIdProperty()).isTrue();
+ }
+
@SuppressWarnings("unchecked")
private Map, Annotation> getAnnotationCache(SamplePersistentProperty property) {
return (Map, Annotation>) ReflectionTestUtils.getField(property, "annotationCache");
@@ -515,6 +524,7 @@ interface NoField {
}
static class JMolecules {
+ @Identity Long identifier;
Association association;
}