Skip to content

Commit b1020d1

Browse files
divyajnu08mp911de
authored andcommitted
Add an option to @Field annotation to include/exclude null values on write.
Properties can be annotated with `@Field(write=…)` to control whether a property with a null value should be included or omitted (default) during conversion in the target Document. Closes #3407 Original pull request: #3646.
1 parent a481636 commit b1020d1

File tree

6 files changed

+83
-0
lines changed

6 files changed

+83
-0
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java

+3
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,9 @@ private void writeProperties(Bson bson, MongoPersistentEntity<?> entity, Persist
744744
Object value = accessor.getProperty(prop);
745745

746746
if (value == null) {
747+
if(!prop.isPropertyOmittableOnNull()) {
748+
writeSimpleInternal(value, bson , prop);
749+
}
747750
continue;
748751
}
749752

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

+14
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,18 @@ public boolean isExplicitLanguageProperty() {
285285
public boolean isTextScoreProperty() {
286286
return isAnnotationPresent(TextScore.class);
287287
}
288+
289+
/*
290+
* (non-Javadoc)
291+
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#isPropertyOmittableOnNull()
292+
*/
293+
public boolean isPropertyOmittableOnNull() {
294+
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(
295+
org.springframework.data.mongodb.core.mapping.Field.class);
296+
297+
if ( annotation != null && annotation.write().equals(Field.Write.ALWAYS) ) {
298+
return false;
299+
}
300+
return true;
301+
}
288302
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/Field.java

+25
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,21 @@
3434
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE })
3535
public @interface Field {
3636

37+
/**
38+
* Enumeration of write strategies for a field with null value.It decides whether a field with null value has to be
39+
* written to the resulting document to be saved to the database.
40+
*/
41+
enum Write{
42+
/*
43+
* The field will always be written to the database irrespective of null value.
44+
*/
45+
ALWAYS,
46+
/*
47+
* The field will only be written to the database if it has a non null value.
48+
*/
49+
NON_NULL
50+
}
51+
3752
/**
3853
* The key to be used to store the field inside the document. Alias for {@link #name()}.
3954
*
@@ -65,4 +80,14 @@
6580
* @since 2.2
6681
*/
6782
FieldType targetType() default FieldType.IMPLICIT;
83+
84+
/**
85+
* If set to {@link Write#NON_NULL} {@literal null} values will be omitted.
86+
* Setting the value to {@link Write#ALWAYS} explicitly adds an entry for the given field
87+
* holding {@literal null} as a value {@code 'fieldName' : null }.
88+
* <p />
89+
* <strong>NOTE</strong> Setting the value to {@link Write#ALWAYS} may lead to increased document size.
90+
* @return {@link Write#NON_NULL} by default.
91+
*/
92+
Write write() default Write.NON_NULL;
6893
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java

+18
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,24 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist
104104
* @since 1.6
105105
*/
106106
boolean isTextScoreProperty();
107+
108+
/**
109+
* Returns whether the property is to be written to the document if the value is null <br/>
110+
* It's annotated with {@link Field.Write}.
111+
*
112+
* @return
113+
* @since 1.6
114+
*/
115+
boolean isPropertyOmittableOnNull();
116+
117+
/**
118+
* Returns whether the property is to be written to the document if the value is null <br/>
119+
* It's annotated with {@link omitNull}.
120+
*
121+
* @return
122+
* @since 1.6
123+
*/
124+
boolean isOmitNullProperty();
107125

108126
/**
109127
* Returns the {@link DBRef} if the property is a reference.

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java

+10
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ public boolean isExplicitLanguageProperty() {
9292
public boolean isTextScoreProperty() {
9393
return delegate.isTextScoreProperty();
9494
}
95+
96+
@Override
97+
public boolean isOmitNullProperty() {
98+
return delegate.isOmitNullProperty();
99+
}
95100

96101
@Override
97102
@Nullable
@@ -315,4 +320,9 @@ public Class<?> getAssociationTargetType() {
315320
public <T> PersistentPropertyAccessor<T> getAccessorForOwner(T owner) {
316321
return delegate.getAccessorForOwner(owner);
317322
}
323+
324+
@Override
325+
public boolean isPropertyOmittableOnNull() {
326+
return delegate.isPropertyOmittableOnNull();
327+
}
318328
}

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java

+13
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ public void shouldDetectTextScorePropertyCorrectly() {
146146
assertThat(property.isTextScoreProperty()).isTrue();
147147
}
148148

149+
@Test // DATAMONGO-2551
150+
public void shouldDetectOmittableOnNullPropertyCorrectly() {
151+
152+
MongoPersistentProperty property = getPropertyFor(DocumentWithOmittableOnNullProperty.class, "write");
153+
assertThat(property.isPropertyOmittableOnNull()).isTrue();
154+
}
155+
149156
@Test // DATAMONGO-976
150157
public void shouldDetectTextScoreAsReadOnlyProperty() {
151158

@@ -297,6 +304,12 @@ static class DocumentWithTextScoreProperty {
297304
@TextScore Float score;
298305
}
299306

307+
static class DocumentWithOmittableOnNullProperty {
308+
309+
@org.springframework.data.mongodb.core.mapping.Field("write") org.springframework.data.mongodb.core.mapping.Field.Write write;
310+
311+
}
312+
300313
static class DocumentWithExplicitlyRenamedIdProperty {
301314

302315
@org.springframework.data.mongodb.core.mapping.Field("id") String id;

0 commit comments

Comments
 (0)