Skip to content

Commit e89d09c

Browse files
committed
DATADOC-144 - Added @Fieldname annotation to allow defining the name of the field a property shall be stored to.
1 parent 3e38595 commit e89d09c

File tree

4 files changed

+156
-1
lines changed

4 files changed

+156
-1
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/document/mongodb/mapping/BasicMongoPersistentProperty.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.util.HashSet;
2222
import java.util.Set;
2323

24+
import org.apache.commons.logging.Log;
25+
import org.apache.commons.logging.LogFactory;
2426
import org.bson.types.ObjectId;
2527
import org.springframework.data.mapping.AnnotationBasedPersistentProperty;
2628
import org.springframework.data.mapping.model.Association;
@@ -34,6 +36,8 @@
3436
*/
3537
public class BasicMongoPersistentProperty extends AnnotationBasedPersistentProperty<MongoPersistentProperty> implements
3638
MongoPersistentProperty {
39+
40+
private static final Log LOG = LogFactory.getLog(BasicMongoPersistentProperty.class);
3741

3842
private static final Set<Class<?>> SUPPORTED_ID_TYPES = new HashSet<Class<?>>();
3943
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<String>();
@@ -56,6 +60,10 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
5660
*/
5761
public BasicMongoPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, MongoPersistentEntity<?> owner) {
5862
super(field, propertyDescriptor, owner);
63+
64+
if (isIdProperty() && field.isAnnotationPresent(FieldName.class)) {
65+
LOG.warn(String.format("Invalid usage of %s on id property. Field name will not be considered!", FieldName.class));
66+
}
5967
}
6068

6169
/* (non-Javadoc)
@@ -87,7 +95,13 @@ public boolean isIdProperty() {
8795
* @return
8896
*/
8997
public String getKey() {
90-
return isIdProperty() ? "_id" : getName();
98+
99+
if (isIdProperty()) {
100+
return "_id";
101+
}
102+
103+
FieldName annotation = getField().getAnnotation(FieldName.class);
104+
return annotation != null ? annotation.value() : getName();
91105
}
92106

93107
/* (non-Javadoc)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright (c) 2011 by the original author(s).
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.document.mongodb.mapping;
17+
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
import java.lang.annotation.Target;
22+
23+
/**
24+
* Annotation to allow defining the name of the field a property should use in a Mongo document. This will cause the
25+
* property annotated being persisted to a field with the configured name as wells as being read from it.
26+
*
27+
* @author Oliver Gierke
28+
*/
29+
@Retention(RetentionPolicy.RUNTIME)
30+
@Target({ ElementType.FIELD })
31+
public @interface FieldName {
32+
33+
String value();
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (c) 2011 by the original author(s).
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.data.document.mongodb.mapping;
17+
18+
import static org.junit.Assert.*;
19+
import static org.hamcrest.CoreMatchers.*;
20+
import java.lang.reflect.Field;
21+
22+
import org.junit.Before;
23+
import org.junit.Test;
24+
import org.springframework.data.annotation.Id;
25+
import org.springframework.data.util.ClassTypeInformation;
26+
import org.springframework.util.ReflectionUtils;
27+
28+
/**
29+
* Unit test for {@link BasicMongoPersistentProperty}.
30+
*
31+
* @author Oliver Gierke
32+
*/
33+
public class BasicMongoPersistentPropertyUnitTests {
34+
35+
MongoPersistentEntity<Person> entity;
36+
37+
@Before
38+
public void setup() {
39+
entity = new BasicMongoPersistentEntity<Person>(ClassTypeInformation.from(Person.class));
40+
}
41+
42+
@Test
43+
public void usesAnnotatedFieldName() {
44+
45+
Field field = ReflectionUtils.findField(Person.class, "firstname");
46+
assertThat(getPropertyFor(field).getKey(), is("foo"));
47+
}
48+
49+
@Test
50+
public void returns_IdForIdProperty() {
51+
Field field = ReflectionUtils.findField(Person.class, "id");
52+
MongoPersistentProperty property = getPropertyFor(field);
53+
assertThat(property.isIdProperty(), is(true));
54+
assertThat(property.getKey(), is("_id"));
55+
}
56+
57+
@Test
58+
public void returnsPropertyNameForUnannotatedProperties() {
59+
60+
Field field = ReflectionUtils.findField(Person.class, "lastname");
61+
assertThat(getPropertyFor(field).getKey(), is("lastname"));
62+
}
63+
64+
private MongoPersistentProperty getPropertyFor(Field field) {
65+
return new BasicMongoPersistentProperty(field, null, entity);
66+
}
67+
68+
class Person {
69+
70+
@Id
71+
String id;
72+
73+
@FieldName("foo")
74+
String firstname;
75+
String lastname;
76+
}
77+
}

spring-data-mongodb/src/test/java/org/springframework/data/document/mongodb/mapping/MappingMongoConverterUnitTests.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,33 @@ public void readsEnumsCorrectly() {
190190
assertThat(result.sampleEnum, is(SampleEnum.FIRST));
191191
}
192192

193+
/**
194+
* @see DATADOC-144
195+
*/
196+
@Test
197+
public void considersFieldNameWhenWriting() {
198+
199+
Person person = new Person();
200+
person.firstname ="Oliver";
201+
202+
DBObject result = new BasicDBObject();
203+
converter.write(person, result);
204+
205+
assertThat(result.containsField("foo"), is(true));
206+
assertThat(result.containsField("firstname"), is(false));
207+
}
208+
209+
/**
210+
* @see DATADOC-144
211+
*/
212+
@Test
213+
public void considersFieldNameWhenReading() {
214+
215+
DBObject dbObject = new BasicDBObject("foo", "Oliver");
216+
Person result = converter.read(Person.class, dbObject);
217+
218+
assertThat(result.firstname, is("Oliver"));
219+
}
193220

194221
class ClassWithEnumProperty {
195222

@@ -211,6 +238,9 @@ interface Contact {
211238

212239
public static class Person implements Contact {
213240
LocalDate birthDate;
241+
242+
@FieldName("foo")
243+
String firstname;
214244
}
215245

216246
static class ClassWithMapProperty {

0 commit comments

Comments
 (0)