Polishing.
Reorder methods and types. Rename MongoPersistentProperty.isOmitNullProperty to writeNullValues. Adapt caching MongoPersistentProperty and add tests. Tweak Javadoc wording, add author and since tags. See #3407 Original pull request: #3646.
This commit is contained in:
@@ -103,6 +103,7 @@ import com.mongodb.DBRef;
|
||||
* @author Mark Paluch
|
||||
* @author Roman Puchkovskiy
|
||||
* @author Heesu Jung
|
||||
* @author Divya Srivastava
|
||||
*/
|
||||
public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware {
|
||||
|
||||
@@ -737,6 +738,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
continue;
|
||||
}
|
||||
if (prop.isAssociation()) {
|
||||
|
||||
writeAssociation(prop.getRequiredAssociation(), accessor, dbObjectAccessor);
|
||||
continue;
|
||||
}
|
||||
@@ -744,13 +746,10 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
Object value = accessor.getProperty(prop);
|
||||
|
||||
if (value == null) {
|
||||
if(!prop.isPropertyOmittableOnNull()) {
|
||||
writeSimpleInternal(value, bson , prop);
|
||||
if (prop.writeNullValues()) {
|
||||
dbObjectAccessor.put(prop, null);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!conversions.isSimpleType(value.getClass())) {
|
||||
} else if (!conversions.isSimpleType(value.getClass())) {
|
||||
writePropertyInternal(value, dbObjectAccessor, prop);
|
||||
} else {
|
||||
writeSimpleInternal(value, bson, prop);
|
||||
@@ -763,7 +762,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
|
||||
|
||||
MongoPersistentProperty inverseProp = association.getInverse();
|
||||
|
||||
writePropertyInternal(accessor.getProperty(inverseProp), dbObjectAccessor, inverseProp);
|
||||
Object value = accessor.getProperty(inverseProp);
|
||||
|
||||
if (value == null && !inverseProp.isUnwrapped() && inverseProp.writeNullValues()) {
|
||||
dbObjectAccessor.put(inverseProp, null);
|
||||
return;
|
||||
}
|
||||
|
||||
writePropertyInternal(value, dbObjectAccessor, inverseProp);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Divya Srivastava
|
||||
*/
|
||||
public class BasicMongoPersistentProperty extends AnnotationBasedPersistentProperty<MongoPersistentProperty>
|
||||
implements MongoPersistentProperty {
|
||||
@@ -214,6 +215,19 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
return annotation != null ? annotation.order() : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#skipNullValues()
|
||||
*/
|
||||
@Override
|
||||
public boolean writeNullValues() {
|
||||
|
||||
org.springframework.data.mongodb.core.mapping.Field annotation = findAnnotation(
|
||||
org.springframework.data.mongodb.core.mapping.Field.class);
|
||||
|
||||
return annotation != null && annotation.write() == Field.Write.ALWAYS;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mapping.model.AbstractPersistentProperty#createAssociation()
|
||||
@@ -286,17 +300,4 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ public class CachingMongoPersistentProperty extends BasicMongoPersistentProperty
|
||||
private boolean dbRefResolved;
|
||||
private @Nullable DBRef dbref;
|
||||
private @Nullable String fieldName;
|
||||
private @Nullable Boolean writeNullValues;
|
||||
private @Nullable Class<?> fieldType;
|
||||
private @Nullable Boolean usePropertyAccess;
|
||||
private @Nullable Boolean isTransient;
|
||||
@@ -90,6 +91,20 @@ public class CachingMongoPersistentProperty extends BasicMongoPersistentProperty
|
||||
return this.fieldName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.BasicMongoPersistentProperty#skipNullValues()
|
||||
*/
|
||||
@Override
|
||||
public boolean writeNullValues() {
|
||||
|
||||
if (this.writeNullValues == null) {
|
||||
this.writeNullValues = super.writeNullValues();
|
||||
}
|
||||
|
||||
return this.writeNullValues;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.mapping.BasicMongoPersistentProperty#getFieldType()
|
||||
|
||||
@@ -28,27 +28,13 @@ import org.springframework.core.annotation.AliasFor;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Divya Srivastava
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@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()}.
|
||||
*
|
||||
@@ -82,12 +68,32 @@ public @interface Field {
|
||||
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 }.
|
||||
* Write rules when to include a property value upon conversion. If set to {@link Write#NON_NULL} (default)
|
||||
* {@literal null} values are not written to the target {@code Document}. 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.
|
||||
* <strong>NOTE</strong>Setting the value to {@link Write#ALWAYS} may lead to increased document size.
|
||||
*
|
||||
* @return {@link Write#NON_NULL} by default.
|
||||
* @since 3.3
|
||||
*/
|
||||
Write write() default Write.NON_NULL;
|
||||
|
||||
/**
|
||||
* Enumeration of write strategies to define when a property is included for write conversion.
|
||||
*
|
||||
* @since 3.3
|
||||
*/
|
||||
enum Write {
|
||||
|
||||
/**
|
||||
* Value that indicates that property is to be always included, independent of value of the property.
|
||||
*/
|
||||
ALWAYS,
|
||||
|
||||
/**
|
||||
* Value that indicates that only properties with non-{@literal null} values are to be included.
|
||||
*/
|
||||
NON_NULL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.lang.Nullable;
|
||||
* @author Patryk Wasik
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Divya Srivastava
|
||||
*/
|
||||
public interface MongoPersistentProperty extends PersistentProperty<MongoPersistentProperty> {
|
||||
|
||||
@@ -54,6 +55,15 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist
|
||||
*/
|
||||
int getFieldOrder();
|
||||
|
||||
/**
|
||||
* Returns whether the property should be written to the database if its value is {@literal null}.
|
||||
*
|
||||
* @return
|
||||
* @since 3.3
|
||||
* @see Field.Write
|
||||
*/
|
||||
boolean writeNullValues();
|
||||
|
||||
/**
|
||||
* Returns whether the property is a {@link com.mongodb.DBRef}. If this returns {@literal true} you can expect
|
||||
* {@link #getDBRef()} to return an non-{@literal null} value.
|
||||
@@ -104,24 +114,6 @@ public interface MongoPersistentProperty extends PersistentProperty<MongoPersist
|
||||
* @since 1.6
|
||||
*/
|
||||
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.
|
||||
|
||||
@@ -63,6 +63,11 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty {
|
||||
return delegate.getFieldOrder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeNullValues() {
|
||||
return delegate.writeNullValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDbReference() {
|
||||
return delegate.isDbReference();
|
||||
@@ -92,11 +97,6 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty {
|
||||
public boolean isTextScoreProperty() {
|
||||
return delegate.isTextScoreProperty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOmitNullProperty() {
|
||||
return delegate.isOmitNullProperty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@@ -321,8 +321,4 @@ class UnwrappedMongoPersistentProperty implements MongoPersistentProperty {
|
||||
return delegate.getAccessorForOwner(owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPropertyOmittableOnNull() {
|
||||
return delegate.isPropertyOmittableOnNull();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
import lombok.With;
|
||||
|
||||
@@ -1692,7 +1693,7 @@ public class MongoTemplateTests {
|
||||
assertThat(template.count(query, collectionName)).isEqualTo(1L);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-571
|
||||
@Test // DATAMONGO-571, GH-3407
|
||||
public void nullsPropertiesForVersionObjectUpdates() {
|
||||
|
||||
VersionedPerson person = new VersionedPerson();
|
||||
@@ -1702,11 +1703,17 @@ public class MongoTemplateTests {
|
||||
template.save(person);
|
||||
assertThat(person.id).isNotNull();
|
||||
|
||||
person.firstname = null;
|
||||
person.lastname = null;
|
||||
template.save(person);
|
||||
|
||||
person = template.findOne(query(where("id").is(person.id)), VersionedPerson.class);
|
||||
assertThat(person.firstname).isNull();
|
||||
assertThat(person.lastname).isNull();
|
||||
|
||||
org.bson.Document document = template.findOne(query(where("_id").is(person.id)), org.bson.Document.class,
|
||||
"versionedPerson");
|
||||
assertThat(document).doesNotContainKey("firstname").containsEntry("lastname", null);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-571
|
||||
@@ -3703,6 +3710,64 @@ public class MongoTemplateTests {
|
||||
assertThat(template.find(new BasicQuery("{}").with(Sort.by("id")), WithIdAndFieldAnnotation.class)).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test // GH-3407
|
||||
void shouldWriteSubdocumentWithNullCorrectly() {
|
||||
|
||||
template.dropCollection(WithSubdocument.class);
|
||||
|
||||
WithSubdocument doc = new WithSubdocument();
|
||||
SubdocumentWithWriteNull subdoc = new SubdocumentWithWriteNull("Walter", "White");
|
||||
doc.subdocument = subdoc;
|
||||
|
||||
template.save(doc);
|
||||
|
||||
org.bson.Document loaded = template.findById(doc.id, org.bson.Document.class, "withSubdocument");
|
||||
|
||||
assertThat(loaded.get("subdocument", org.bson.Document.class)).hasSize(3).containsEntry("firstname", "Walter")
|
||||
.containsEntry("nickname", null);
|
||||
}
|
||||
|
||||
@Test // GH-3407
|
||||
void shouldUpdateSubdocumentWithNullCorrectly() {
|
||||
|
||||
template.dropCollection(WithSubdocument.class);
|
||||
|
||||
WithSubdocument doc = new WithSubdocument();
|
||||
SubdocumentWithWriteNull subdoc = new SubdocumentWithWriteNull("Walter", "White");
|
||||
subdoc.nickname = "Heisenberg";
|
||||
doc.subdocument = subdoc;
|
||||
|
||||
template.save(doc);
|
||||
|
||||
String id = doc.id;
|
||||
|
||||
doc.id = null;
|
||||
subdoc.nickname = null;
|
||||
template.update(WithSubdocument.class).replaceWith(doc).findAndReplaceValue();
|
||||
|
||||
org.bson.Document loaded = template.findById(id, org.bson.Document.class, "withSubdocument");
|
||||
|
||||
assertThat(loaded.get("subdocument", org.bson.Document.class)).hasSize(3).containsEntry("firstname", "Walter")
|
||||
.containsEntry("nickname", null);
|
||||
}
|
||||
|
||||
@Test // GH-3407
|
||||
void shouldFindSubdocumentWithNullCorrectly() {
|
||||
|
||||
template.dropCollection(WithSubdocument.class);
|
||||
|
||||
WithSubdocument doc = new WithSubdocument();
|
||||
SubdocumentWithWriteNull subdoc = new SubdocumentWithWriteNull("Walter", "White");
|
||||
doc.subdocument = subdoc;
|
||||
|
||||
template.save(doc);
|
||||
|
||||
org.bson.Document loaded = template.findOne(query(where("subdocument").is(subdoc)), org.bson.Document.class,
|
||||
"withSubdocument");
|
||||
|
||||
assertThat(loaded).isNotNull();
|
||||
}
|
||||
|
||||
private AtomicReference<ImmutableVersioned> createAfterSaveReference() {
|
||||
|
||||
AtomicReference<ImmutableVersioned> saved = new AtomicReference<>();
|
||||
@@ -4020,7 +4085,8 @@ public class MongoTemplateTests {
|
||||
static class VersionedPerson {
|
||||
|
||||
@Version Long version;
|
||||
String id, firstname, lastname;
|
||||
String id, firstname;
|
||||
@Field(write = Field.Write.ALWAYS) String lastname;
|
||||
}
|
||||
|
||||
static class TypeWithFieldAnnotation {
|
||||
@@ -4247,4 +4313,22 @@ public class MongoTemplateTests {
|
||||
String value;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
static class WithSubdocument {
|
||||
|
||||
@Id //
|
||||
@Field(name = "_id") //
|
||||
String id;
|
||||
SubdocumentWithWriteNull subdocument;
|
||||
}
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor
|
||||
static class SubdocumentWithWriteNull {
|
||||
|
||||
final String firstname, lastname;
|
||||
|
||||
@Field(write = Field.Write.ALWAYS) String nickname;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1139,7 +1139,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
.containsEntry("$geoNear.near.coordinates.[1]", 2D);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2155
|
||||
@Test // DATAMONGO-2155, GH-3407
|
||||
void saveVersionedEntityShouldCallUpdateCorrectly() {
|
||||
|
||||
when(updateResult.getModifiedCount()).thenReturn(1L);
|
||||
@@ -1157,7 +1157,7 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
|
||||
assertThat(queryCaptor.getValue()).isEqualTo(new Document("_id", 1).append("version", 10));
|
||||
assertThat(updateCaptor.getValue())
|
||||
.isEqualTo(new Document("version", 11).append("_class", VersionedEntity.class.getName()));
|
||||
.isEqualTo(new Document("version", 11).append("_class", VersionedEntity.class.getName()).append("name", null));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1783
|
||||
@@ -2273,6 +2273,8 @@ public class MongoTemplateUnitTests extends MongoOperationsUnitTests {
|
||||
|
||||
@Id Integer id;
|
||||
@Version Integer version;
|
||||
|
||||
@Field(write = Field.Write.ALWAYS) String name;
|
||||
}
|
||||
|
||||
enum MyConverter implements Converter<AutogenerateableId, String> {
|
||||
|
||||
@@ -2520,6 +2520,18 @@ class MappingMongoConverterUnitTests {
|
||||
assertThat(target.typeImplementingMap).isEqualTo(new TypeImplementingMap("one", 2));
|
||||
}
|
||||
|
||||
@Test // GH-3407
|
||||
void shouldWriteNullPropertyCorrectly() {
|
||||
|
||||
WithFieldWrite fieldWrite = new WithFieldWrite();
|
||||
|
||||
org.bson.Document document = new org.bson.Document();
|
||||
converter.write(fieldWrite, document);
|
||||
|
||||
assertThat(document).containsEntry("writeAlways", null).doesNotContainKey("writeNonNull");
|
||||
assertThat(document).containsEntry("writeAlwaysPerson", null).doesNotContainKey("writeNonNullPerson");
|
||||
}
|
||||
|
||||
static class GenericType<T> {
|
||||
T content;
|
||||
}
|
||||
@@ -3165,4 +3177,20 @@ class MappingMongoConverterUnitTests {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class WithFieldWrite {
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Field(
|
||||
write = org.springframework.data.mongodb.core.mapping.Field.Write.NON_NULL) Integer writeNonNull;
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Field(
|
||||
write = org.springframework.data.mongodb.core.mapping.Field.Write.ALWAYS) Integer writeAlways;
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef @org.springframework.data.mongodb.core.mapping.Field(
|
||||
write = org.springframework.data.mongodb.core.mapping.Field.Write.NON_NULL) Person writeNonNullPerson;
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.DBRef @org.springframework.data.mongodb.core.mapping.Field(
|
||||
write = org.springframework.data.mongodb.core.mapping.Field.Write.ALWAYS) Person writeAlwaysPerson;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,25 +48,26 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Oliver Gierke
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
* @author Divya Srivastava
|
||||
*/
|
||||
public class BasicMongoPersistentPropertyUnitTests {
|
||||
|
||||
MongoPersistentEntity<Person> entity;
|
||||
private MongoPersistentEntity<Person> entity;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
entity = new BasicMongoPersistentEntity<>(ClassTypeInformation.from(Person.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesAnnotatedFieldName() {
|
||||
void usesAnnotatedFieldName() {
|
||||
|
||||
Field field = ReflectionUtils.findField(Person.class, "firstname");
|
||||
assertThat(getPropertyFor(field).getFieldName()).isEqualTo("foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returns_IdForIdProperty() {
|
||||
void returns_IdForIdProperty() {
|
||||
Field field = ReflectionUtils.findField(Person.class, "id");
|
||||
MongoPersistentProperty property = getPropertyFor(field);
|
||||
assertThat(property.isIdProperty()).isTrue();
|
||||
@@ -74,19 +75,19 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnsPropertyNameForUnannotatedProperties() {
|
||||
void returnsPropertyNameForUnannotatedProperties() {
|
||||
|
||||
Field field = ReflectionUtils.findField(Person.class, "lastname");
|
||||
assertThat(getPropertyFor(field).getFieldName()).isEqualTo("lastname");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preventsNegativeOrder() {
|
||||
void preventsNegativeOrder() {
|
||||
getPropertyFor(ReflectionUtils.findField(Person.class, "ssn"));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-553
|
||||
public void usesPropertyAccessForThrowableCause() {
|
||||
void usesPropertyAccessForThrowableCause() {
|
||||
|
||||
BasicMongoPersistentEntity<Throwable> entity = new BasicMongoPersistentEntity<>(
|
||||
ClassTypeInformation.from(Throwable.class));
|
||||
@@ -96,7 +97,7 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-607
|
||||
public void usesCustomFieldNamingStrategyByDefault() throws Exception {
|
||||
void usesCustomFieldNamingStrategyByDefault() throws Exception {
|
||||
|
||||
ClassTypeInformation<Person> type = ClassTypeInformation.from(Person.class);
|
||||
Field field = ReflectionUtils.findField(Person.class, "lastname");
|
||||
@@ -113,7 +114,7 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-607
|
||||
public void rejectsInvalidValueReturnedByFieldNamingStrategy() {
|
||||
void rejectsInvalidValueReturnedByFieldNamingStrategy() {
|
||||
|
||||
ClassTypeInformation<Person> type = ClassTypeInformation.from(Person.class);
|
||||
Field field = ReflectionUtils.findField(Person.class, "lastname");
|
||||
@@ -126,49 +127,42 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-937
|
||||
public void shouldDetectAnnotatedLanguagePropertyCorrectly() {
|
||||
void shouldDetectAnnotatedLanguagePropertyCorrectly() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithLanguageProperty.class, "lang");
|
||||
assertThat(property.isLanguageProperty()).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-937
|
||||
public void shouldDetectImplicitLanguagePropertyCorrectly() {
|
||||
void shouldDetectImplicitLanguagePropertyCorrectly() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithImplicitLanguageProperty.class, "language");
|
||||
assertThat(property.isLanguageProperty()).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-976
|
||||
public void shouldDetectTextScorePropertyCorrectly() {
|
||||
void shouldDetectTextScorePropertyCorrectly() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithTextScoreProperty.class, "score");
|
||||
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() {
|
||||
void shouldDetectTextScoreAsReadOnlyProperty() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithTextScoreProperty.class, "score");
|
||||
assertThat(property.isWritable()).isFalse();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1050
|
||||
public void shouldNotConsiderExplicitlyNameFieldAsIdProperty() {
|
||||
void shouldNotConsiderExplicitlyNameFieldAsIdProperty() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithExplicitlyRenamedIdProperty.class, "id");
|
||||
assertThat(property.isIdProperty()).isFalse();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1050
|
||||
public void shouldConsiderPropertyAsIdWhenExplicitlyAnnotatedWithIdEvenWhenExplicitlyNamePresent() {
|
||||
void shouldConsiderPropertyAsIdWhenExplicitlyAnnotatedWithIdEvenWhenExplicitlyNamePresent() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithExplicitlyRenamedIdPropertyHavingIdAnnotation.class,
|
||||
"id");
|
||||
@@ -176,7 +170,7 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1373
|
||||
public void shouldConsiderComposedAnnotationsForIdField() {
|
||||
void shouldConsiderComposedAnnotationsForIdField() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithComposedAnnotations.class, "myId");
|
||||
assertThat(property.isIdProperty()).isTrue();
|
||||
@@ -184,14 +178,14 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1373
|
||||
public void shouldConsiderComposedAnnotationsForFields() {
|
||||
void shouldConsiderComposedAnnotationsForFields() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(DocumentWithComposedAnnotations.class, "myField");
|
||||
assertThat(property.getFieldName()).isEqualTo("myField");
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1737
|
||||
public void honorsFieldOrderWhenIteratingOverProperties() {
|
||||
void honorsFieldOrderWhenIteratingOverProperties() {
|
||||
|
||||
MongoMappingContext context = new MongoMappingContext();
|
||||
MongoPersistentEntity<?> entity = context.getPersistentEntity(Sample.class);
|
||||
@@ -203,36 +197,45 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
assertThat(properties).containsExactly("first", "second", "third");
|
||||
}
|
||||
|
||||
@Test // GH-3407
|
||||
void shouldDetectWritability() {
|
||||
|
||||
assertThat(getPropertyFor(WithFieldWrite.class, "fieldWithDefaults").writeNullValues()).isFalse();
|
||||
assertThat(getPropertyFor(WithFieldWrite.class, "fieldWithField").writeNullValues()).isFalse();
|
||||
assertThat(getPropertyFor(WithFieldWrite.class, "writeNonNull").writeNullValues()).isFalse();
|
||||
assertThat(getPropertyFor(WithFieldWrite.class, "writeAlways").writeNullValues()).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1798
|
||||
public void fieldTypeShouldReturnActualTypeForNonIdProperties() {
|
||||
void fieldTypeShouldReturnActualTypeForNonIdProperties() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(Person.class, "lastname");
|
||||
assertThat(property.getFieldType()).isEqualTo(String.class);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1798
|
||||
public void fieldTypeShouldBeObjectIdForPropertiesAnnotatedWithCommonsId() {
|
||||
void fieldTypeShouldBeObjectIdForPropertiesAnnotatedWithCommonsId() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(Person.class, "id");
|
||||
assertThat(property.getFieldType()).isEqualTo(ObjectId.class);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1798
|
||||
public void fieldTypeShouldBeImplicitForPropertiesAnnotatedWithMongoId() {
|
||||
void fieldTypeShouldBeImplicitForPropertiesAnnotatedWithMongoId() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(WithStringMongoId.class, "id");
|
||||
assertThat(property.getFieldType()).isEqualTo(String.class);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1798
|
||||
public void fieldTypeShouldBeObjectIdForPropertiesAnnotatedWithMongoIdAndTargetTypeObjectId() {
|
||||
void fieldTypeShouldBeObjectIdForPropertiesAnnotatedWithMongoIdAndTargetTypeObjectId() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(WithStringMongoIdMappedToObjectId.class, "id");
|
||||
assertThat(property.getFieldType()).isEqualTo(ObjectId.class);
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2460
|
||||
public void fieldTypeShouldBeDocumentForPropertiesAnnotatedIdWhenAComplexTypeAndFieldTypeImplicit() {
|
||||
void fieldTypeShouldBeDocumentForPropertiesAnnotatedIdWhenAComplexTypeAndFieldTypeImplicit() {
|
||||
|
||||
MongoPersistentProperty property = getPropertyFor(WithComplexId.class, "id");
|
||||
assertThat(property.getFieldType()).isEqualTo(Document.class);
|
||||
@@ -304,9 +307,15 @@ public class BasicMongoPersistentPropertyUnitTests {
|
||||
@TextScore Float score;
|
||||
}
|
||||
|
||||
static class DocumentWithOmittableOnNullProperty {
|
||||
static class WithFieldWrite {
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Field("write") org.springframework.data.mongodb.core.mapping.Field.Write write;
|
||||
int fieldWithDefaults;
|
||||
@org.springframework.data.mongodb.core.mapping.Field int fieldWithField;
|
||||
@org.springframework.data.mongodb.core.mapping.Field(
|
||||
write = org.springframework.data.mongodb.core.mapping.Field.Write.NON_NULL) Integer writeNonNull;
|
||||
|
||||
@org.springframework.data.mongodb.core.mapping.Field(
|
||||
write = org.springframework.data.mongodb.core.mapping.Field.Write.ALWAYS) Integer writeAlways;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
== What's New in Spring Data MongoDB 3.3
|
||||
|
||||
* Extended support for <<mapping-usage.document-references, referencing>> entities.
|
||||
* Include/exclude `null` properties on write to `Document` through `@Field(write=…)`.
|
||||
|
||||
[[new-features.3.2]]
|
||||
== What's New in Spring Data MongoDB 3.2
|
||||
|
||||
Reference in New Issue
Block a user