diff --git a/pom.xml b/pom.xml
index 75745189ed..50eee8ac02 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.7.0.BUILD-SNAPSHOT
+ 1.7.0.DATAMONGO-1050-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml
index 40e8a0f253..f39ae4f5a7 100644
--- a/spring-data-mongodb-cross-store/pom.xml
+++ b/spring-data-mongodb-cross-store/pom.xml
@@ -6,7 +6,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.7.0.BUILD-SNAPSHOT
+ 1.7.0.DATAMONGO-1050-SNAPSHOT
../pom.xml
@@ -48,7 +48,7 @@
org.springframework.data
spring-data-mongodb
- 1.7.0.BUILD-SNAPSHOT
+ 1.7.0.DATAMONGO-1050-SNAPSHOT
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index 13110137b6..ff00d2742c 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.7.0.BUILD-SNAPSHOT
+ 1.7.0.DATAMONGO-1050-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-log4j/pom.xml b/spring-data-mongodb-log4j/pom.xml
index 6ff09e4577..7d1af7a511 100644
--- a/spring-data-mongodb-log4j/pom.xml
+++ b/spring-data-mongodb-log4j/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.7.0.BUILD-SNAPSHOT
+ 1.7.0.DATAMONGO-1050-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index bfcacd66eb..ec09fec9df 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -11,7 +11,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.7.0.BUILD-SNAPSHOT
+ 1.7.0.DATAMONGO-1050-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java
index bde3c63bde..4680791d1f 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java
@@ -100,7 +100,8 @@ public boolean isIdProperty() {
}
// We need to support a wider range of ID types than just the ones that can be converted to an ObjectId
- return SUPPORTED_ID_PROPERTY_NAMES.contains(getName());
+ // but still we need to check if there happens to be an explicit name set
+ return SUPPORTED_ID_PROPERTY_NAMES.contains(getName()) && !hasExplicitFieldName();
}
/*
@@ -134,10 +135,8 @@ public String getFieldName() {
}
}
- org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
-
- if (annotation != null && StringUtils.hasText(annotation.value())) {
- return annotation.value();
+ if (hasExplicitFieldName()) {
+ return getAnnotatedFieldName();
}
String fieldName = fieldNamingStrategy.getFieldName(this);
@@ -150,6 +149,26 @@ public String getFieldName() {
return fieldName;
}
+ /**
+ * @return true if {@link org.springframework.data.mongodb.core.mapping.Field} having non blank
+ * {@link org.springframework.data.mongodb.core.mapping.Field#value()} present.
+ * @since 1.7
+ */
+ protected boolean hasExplicitFieldName() {
+ return StringUtils.hasText(getAnnotatedFieldName());
+ }
+
+ private String getAnnotatedFieldName() {
+
+ org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);
+
+ if (annotation != null && StringUtils.hasText(annotation.value())) {
+ return annotation.value();
+ }
+
+ return null;
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#getFieldOrder()
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java
index 0cdb405ade..26ce313497 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java
@@ -15,10 +15,26 @@
*/
package org.springframework.data.mongodb.core.convert;
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.*;
-import static org.springframework.data.mongodb.core.DBObjectTestUtils.*;
+import static org.hamcrest.Matchers.arrayWithSize;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.springframework.data.mongodb.core.DBObjectTestUtils.getAsDBObject;
+import static org.springframework.data.mongodb.core.DBObjectTestUtils.getTypedValue;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -83,6 +99,7 @@
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
+import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
@@ -1869,6 +1886,81 @@ public void readShouldRespectExplicitFieldNameForDbRef() {
Mockito.any(DbRefResolverCallback.class), Mockito.any(DbRefProxyHandler.class));
}
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void writeShouldUseExplicitFieldnameForIdPropertyWhenAnnotated() {
+
+ RootForClassWithExplicitlyRenamedIdField source = new RootForClassWithExplicitlyRenamedIdField();
+ source.id = "rootId";
+ source.nested = new ClassWithExplicitlyRenamedField();
+ source.nested.id = "nestedId";
+
+ DBObject sink = new BasicDBObject();
+ converter.write(source, sink);
+
+ assertThat((String) sink.get("_id"), is("rootId"));
+ assertThat((DBObject) sink.get("nested"), is(new BasicDBObjectBuilder().add("id", "nestedId").get()));
+ }
+
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void readShouldUseExplicitFieldnameForIdPropertyWhenAnnotated() {
+
+ DBObject source = new BasicDBObjectBuilder().add("_id", "rootId")
+ .add("nested", new BasicDBObject("id", "nestedId")).get();
+
+ RootForClassWithExplicitlyRenamedIdField sink = converter.read(RootForClassWithExplicitlyRenamedIdField.class,
+ source);
+
+ assertThat(sink.id, is("rootId"));
+ assertThat(sink.nested, notNullValue());
+ assertThat(sink.nested.id, is("nestedId"));
+ }
+
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void namedIdFieldShouldExtractValueFromUnderscoreIdField() {
+
+ DBObject dbo = new BasicDBObjectBuilder().add("_id", "A").add("id", "B").get();
+
+ ClassWithNamedIdField withNamedIdField = converter.read(ClassWithNamedIdField.class, dbo);
+
+ assertThat(withNamedIdField.id, is("A"));
+ }
+
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void explicitlyRenamedIfFieldShouldExtractValueFromIdField() {
+
+ DBObject dbo = new BasicDBObjectBuilder().add("_id", "A").add("id", "B").get();
+
+ ClassWithExplicitlyRenamedField withExplicitlyRenamedField = converter.read(ClassWithExplicitlyRenamedField.class,
+ dbo);
+
+ assertThat(withExplicitlyRenamedField.id, is("B"));
+ }
+
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void annotatedIdFieldShouldExtractValueFromUnderscoreIdField() {
+
+ DBObject dbo = new BasicDBObjectBuilder().add("_id", "A").add("id", "B").get();
+
+ ClassWithAnnotatedIdField withAnnotatedIdField = converter.read(ClassWithAnnotatedIdField.class, dbo);
+
+ assertThat(withAnnotatedIdField.key, is("A"));
+ }
+
static class GenericType {
T content;
}
@@ -2128,6 +2220,32 @@ class ClassWithExplicitlyNamedDBRefProperty {
public ClassWithIntId getDbRefProperty() {
return dbRefProperty;
}
+ }
+
+ static class RootForClassWithExplicitlyRenamedIdField {
+
+ @Id String id;
+ ClassWithExplicitlyRenamedField nested;
+ }
+
+ static class ClassWithExplicitlyRenamedField {
+
+ @Field("id") String id;
+ }
+
+ static class RootForClassWithNamedIdField {
+
+ String id;
+ ClassWithNamedIdField nested;
+ }
+
+ static class ClassWithNamedIdField {
+
+ String id;
+ }
+
+ static class ClassWithAnnotatedIdField {
+ @Id String key;
}
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java
index 1fa54024eb..5de72b45f9 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java
@@ -659,6 +659,7 @@ public void getMappedSortIgnoresTextScoreWhenNotSortedByScore() {
}
/**
+<<<<<<< HEAD
* @see DATAMONGO-1070
*/
@Test
@@ -673,6 +674,34 @@ public void mapsIdReferenceToDBRefCorrectly() {
com.mongodb.DBRef reference = getTypedValue(result, "reference", com.mongodb.DBRef.class);
assertThat(reference.getId(), is(instanceOf(ObjectId.class)));
}
+
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void shouldUseExplicitlySetFieldnameForIdPropertyCandidates() {
+
+ Query query = query(where("nested.id").is("bar"));
+
+ DBObject dbo = mapper.getMappedObject(query.getQueryObject(),
+ context.getPersistentEntity(RootForClassWithExplicitlyRenamedIdField.class));
+
+ assertThat(dbo, equalTo(new BasicDBObjectBuilder().add("nested.id", "bar").get()));
+ }
+
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void shouldUseExplicitlySetFieldnameForIdPropertyCandidatesUsedInSortClause() {
+
+ Query query = new Query().with(new Sort("nested.id"));
+
+ DBObject dbo = mapper.getMappedSort(query.getSortObject(),
+ context.getPersistentEntity(RootForClassWithExplicitlyRenamedIdField.class));
+
+ assertThat(dbo, equalTo(new BasicDBObjectBuilder().add("nested.id", 1).get()));
+ }
@Document
public class Foo {
@@ -755,4 +784,15 @@ class WithTextScoreProperty {
@Id String id;
@TextScore @Field("score") Float textScore;
}
+
+ static class RootForClassWithExplicitlyRenamedIdField {
+
+ @Id String id;
+ ClassWithExplicitlyRenamedField nested;
+ }
+
+ static class ClassWithExplicitlyRenamedField {
+
+ @Field("id") String id;
+ }
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java
index 104791b37b..0dc781df1a 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java
@@ -130,10 +130,7 @@ public void rejectsInvalidValueReturnedByFieldNamingStrategy() {
@Test
public void shouldDetectAnnotatedLanguagePropertyCorrectly() {
- BasicMongoPersistentEntity persistentEntity = new BasicMongoPersistentEntity(
- ClassTypeInformation.from(DocumentWithLanguageProperty.class));
-
- MongoPersistentProperty property = getPropertyFor(persistentEntity, "lang");
+ MongoPersistentProperty property = getPropertyFor(DocumentWithLanguageProperty.class, "lang");
assertThat(property.isLanguageProperty(), is(true));
}
@@ -143,10 +140,7 @@ public void shouldDetectAnnotatedLanguagePropertyCorrectly() {
@Test
public void shouldDetectIplicitLanguagePropertyCorrectly() {
- BasicMongoPersistentEntity persistentEntity = new BasicMongoPersistentEntity(
- ClassTypeInformation.from(DocumentWithImplicitLanguageProperty.class));
-
- MongoPersistentProperty property = getPropertyFor(persistentEntity, "language");
+ MongoPersistentProperty property = getPropertyFor(DocumentWithImplicitLanguageProperty.class, "language");
assertThat(property.isLanguageProperty(), is(true));
}
@@ -156,10 +150,7 @@ public void shouldDetectIplicitLanguagePropertyCorrectly() {
@Test
public void shouldDetectTextScorePropertyCorrectly() {
- BasicMongoPersistentEntity persistentEntity = new BasicMongoPersistentEntity(
- ClassTypeInformation.from(DocumentWithTextScoreProperty.class));
-
- MongoPersistentProperty property = getPropertyFor(persistentEntity, "score");
+ MongoPersistentProperty property = getPropertyFor(DocumentWithTextScoreProperty.class, "score");
assertThat(property.isTextScoreProperty(), is(true));
}
@@ -169,17 +160,39 @@ public void shouldDetectTextScorePropertyCorrectly() {
@Test
public void shouldDetectTextScoreAsReadOnlyProperty() {
- BasicMongoPersistentEntity persistentEntity = new BasicMongoPersistentEntity(
- ClassTypeInformation.from(DocumentWithTextScoreProperty.class));
-
- MongoPersistentProperty property = getPropertyFor(persistentEntity, "score");
+ MongoPersistentProperty property = getPropertyFor(DocumentWithTextScoreProperty.class, "score");
assertThat(property.isWritable(), is(false));
}
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void shouldNotConsiderExplicitlyNameFieldAsIdProperty() {
+
+ MongoPersistentProperty property = getPropertyFor(DocumentWithExplicitlyRenamedIdProperty.class, "id");
+ assertThat(property.isIdProperty(), is(false));
+ }
+
+ /**
+ * @see DATAMONGO-1050
+ */
+ @Test
+ public void shouldConsiderPropertyAsIdWhenExplicitlyAnnotatedWithIdEvenWhenExplicitlyNamePresent() {
+
+ MongoPersistentProperty property = getPropertyFor(DocumentWithExplicitlyRenamedIdPropertyHavingIdAnnotation.class,
+ "id");
+ assertThat(property.isIdProperty(), is(true));
+ }
+
private MongoPersistentProperty getPropertyFor(Field field) {
return getPropertyFor(entity, field);
}
+ private MongoPersistentProperty getPropertyFor(Class type, String fieldname) {
+ return getPropertyFor(new BasicMongoPersistentEntity(ClassTypeInformation.from(type)), fieldname);
+ }
+
private MongoPersistentProperty getPropertyFor(MongoPersistentEntity> persistentEntity, String fieldname) {
return getPropertyFor(persistentEntity, ReflectionUtils.findField(persistentEntity.getType(), fieldname));
}
@@ -230,4 +243,14 @@ static class DocumentWithImplicitLanguageProperty {
static class DocumentWithTextScoreProperty {
@TextScore Float score;
}
+
+ static class DocumentWithExplicitlyRenamedIdProperty {
+
+ @org.springframework.data.mongodb.core.mapping.Field("id") String id;
+ }
+
+ static class DocumentWithExplicitlyRenamedIdPropertyHavingIdAnnotation {
+
+ @Id @org.springframework.data.mongodb.core.mapping.Field("id") String id;
+ }
}