Browse Source

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.
pull/860/head
Divya Srivastava 5 years ago committed by Mark Paluch
parent
commit
b1020d19ba
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 3
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
  2. 14
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java
  3. 25
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/Field.java
  4. 18
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java
  5. 10
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/UnwrappedMongoPersistentProperty.java
  6. 13
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java

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

@ -744,6 +744,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App @@ -744,6 +744,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
Object value = accessor.getProperty(prop);
if (value == null) {
if(!prop.isPropertyOmittableOnNull()) {
writeSimpleInternal(value, bson , prop);
}
continue;
}

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

@ -285,4 +285,18 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope @@ -285,4 +285,18 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
public boolean isTextScoreProperty() {
return isAnnotationPresent(TextScore.class);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#isPropertyOmittableOnNull()
*/
public boolean isPropertyOmittableOnNull() {
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(
org.springframework.data.mongodb.core.mapping.Field.class);
if ( annotation != null && annotation.write().equals(Field.Write.ALWAYS) ) {
return false;
}
return true;
}
}

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

@ -34,6 +34,21 @@ import org.springframework.core.annotation.AliasFor; @@ -34,6 +34,21 @@ import org.springframework.core.annotation.AliasFor;
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE })
public @interface Field {
/**
* Enumeration of write strategies for a field with null value.It decides whether a field with null value has to be
* written to the resulting document to be saved to the database.
*/
enum Write{
/*
* The field will always be written to the database irrespective of null value.
*/
ALWAYS,
/*
* The field will only be written to the database if it has a non null value.
*/
NON_NULL
}
/**
* The key to be used to store the field inside the document. Alias for {@link #name()}.
*
@ -65,4 +80,14 @@ public @interface Field { @@ -65,4 +80,14 @@ public @interface Field {
* @since 2.2
*/
FieldType targetType() default FieldType.IMPLICIT;
/**
* If set to {@link Write#NON_NULL} {@literal null} values will be omitted.
* Setting the value to {@link Write#ALWAYS} explicitly adds an entry for the given field
* holding {@literal null} as a value {@code 'fieldName' : null }.
* <p />
* <strong>NOTE</strong> Setting the value to {@link Write#ALWAYS} may lead to increased document size.
* @return {@link Write#NON_NULL} by default.
*/
Write write() default Write.NON_NULL;
}

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

@ -105,6 +105,24 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist @@ -105,6 +105,24 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist
*/
boolean isTextScoreProperty();
/**
* Returns whether the property is to be written to the document if the value is null <br/>
* It's annotated with {@link Field.Write}.
*
* @return
* @since 1.6
*/
boolean isPropertyOmittableOnNull();
/**
* Returns whether the property is to be written to the document if the value is null <br/>
* It's annotated with {@link omitNull}.
*
* @return
* @since 1.6
*/
boolean isOmitNullProperty();
/**
* Returns the {@link DBRef} if the property is a reference.
*

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

@ -93,6 +93,11 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty { @@ -93,6 +93,11 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty {
return delegate.isTextScoreProperty();
}
@Override
public boolean isOmitNullProperty() {
return delegate.isOmitNullProperty();
}
@Override
@Nullable
public DBRef getDBRef() {
@ -315,4 +320,9 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty { @@ -315,4 +320,9 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty {
public <T> PersistentPropertyAccessor<T> getAccessorForOwner(T owner) {
return delegate.getAccessorForOwner(owner);
}
@Override
public boolean isPropertyOmittableOnNull() {
return delegate.isPropertyOmittableOnNull();
}
}

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

@ -146,6 +146,13 @@ public class BasicMongoPersistentPropertyUnitTests { @@ -146,6 +146,13 @@ public class BasicMongoPersistentPropertyUnitTests {
assertThat(property.isTextScoreProperty()).isTrue();
}
@Test // DATAMONGO-2551
public void shouldDetectOmittableOnNullPropertyCorrectly() {
MongoPersistentProperty property = getPropertyFor(DocumentWithOmittableOnNullProperty.class, "write");
assertThat(property.isPropertyOmittableOnNull()).isTrue();
}
@Test // DATAMONGO-976
public void shouldDetectTextScoreAsReadOnlyProperty() {
@ -297,6 +304,12 @@ public class BasicMongoPersistentPropertyUnitTests { @@ -297,6 +304,12 @@ public class BasicMongoPersistentPropertyUnitTests {
@TextScore Float score;
}
static class DocumentWithOmittableOnNullProperty {
@org.springframework.data.mongodb.core.mapping.Field("write") org.springframework.data.mongodb.core.mapping.Field.Write write;
}
static class DocumentWithExplicitlyRenamedIdProperty {
@org.springframework.data.mongodb.core.mapping.Field("id") String id;

Loading…
Cancel
Save