From 7a57a235d86f4a03250b9145881f56f343a3658e Mon Sep 17 00:00:00 2001 From: Geoffrey Mina Date: Fri, 20 May 2016 17:48:07 +0200 Subject: [PATCH] DATACOUCH-226 - Enable strict `@Field` mapping If the MappingCouchbaseConverter strict mode is enabled and no annotation is present, the property will not be eligible for document mapping. This allows to specifically ignore some attributes in Couchbase only. For generally ignoring attributes in any Spring Data backing store, prefer the standard `@Transient`. Closes #112 --- .../convert/MappingCouchbaseConverter.java | 24 +++++++++ .../MappingCouchbaseConverterTests.java | 51 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java b/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java index e8917f4f..e28920ea 100644 --- a/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java +++ b/src/main/java/org/springframework/data/couchbase/core/convert/MappingCouchbaseConverter.java @@ -23,6 +23,8 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import com.couchbase.client.java.repository.annotation.Field; + import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.CollectionFactory; @@ -61,6 +63,7 @@ import org.springframework.util.CollectionUtils; * * @author Michael Nitschinger * @author Oliver Gierke + * @author Geoffrey Mina */ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter implements ApplicationContextAware { @@ -99,6 +102,11 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter */ private final SpELContext spELContext; + /** + * Enable strict @Field checking on mapper + */ + private boolean enableStrictFieldChecking = false; + /** * Create a new {@link MappingCouchbaseConverter}. * @@ -135,6 +143,20 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter return typeMapper.getTypeKey(); } + /** + * Toggles strict checking of the couchbase {@link Field} annotation. If enabled, + * strict checking will prevent non-annotated properties to be serialized. This only + * applies to the Couchbase datastore, allowing other Spring Data datastores to still + * deal with the property. + * + * @param enableStrictFieldChecking true to only consider Field-annotated properties for + * Couchbase serialization. + * @see DATACOUCH-226 + */ + public void setEnableStrictFieldChecking(boolean enableStrictFieldChecking){ + this.enableStrictFieldChecking = enableStrictFieldChecking; + } + @Override public R read(final Class clazz, final CouchbaseDocument source) { return read(ClassTypeInformation.from(clazz), source, null); @@ -434,6 +456,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter public void doWithPersistentProperty(final CouchbasePersistentProperty prop) { if (prop.equals(idProperty) || (versionProperty != null && prop.equals(versionProperty))) { return; + } else if(enableStrictFieldChecking && !prop.isAnnotationPresent(Field.class)){ + return; } Object propertyObj = accessor.getProperty(prop, prop.getType()); diff --git a/src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java b/src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java index 4912c3fd..c4c9d5cd 100644 --- a/src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java +++ b/src/test/java/org/springframework/data/couchbase/core/mapping/MappingCouchbaseConverterTests.java @@ -33,6 +33,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; +import com.couchbase.client.java.repository.annotation.Field; import org.joda.time.LocalDateTime; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,6 +52,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Michael Nitschinger + * @author Geoffrey Mina */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = UnitTestApplicationConfig.class) @@ -501,6 +503,41 @@ public class MappingCouchbaseConverterTests { assertEquals("springId", converted.getId()); } + @Test + public void testStrictFieldCheckingIgnoresUnannotated() throws Exception{ + try { + CouchbaseDocument converted = new CouchbaseDocument(); + AnnotatedEntity entity = new AnnotatedEntity(); + + converter.setEnableStrictFieldChecking(true); + converter.write(entity,converted); + + assertTrue(converted.getId() != null); + assertTrue(converted.getPayload().containsKey("annotatedField")); + assertFalse(converted.getPayload().containsKey("nonAnnotatedField")); + } finally { + converter.setEnableStrictFieldChecking(false); + } + } + + @Test + public void testLenientFieldCheckingStoresUnannotated() throws Exception{ + try { + CouchbaseDocument converted = new CouchbaseDocument(); + AnnotatedEntity entity = new AnnotatedEntity(); + + converter.setEnableStrictFieldChecking(false); + converter.write(entity,converted); + + assertTrue(converted.getId() != null); + assertTrue(converted.getPayload().containsKey("annotatedField")); + assertTrue(converted.getPayload().containsKey("nonAnnotatedField")); + } finally { + converter.setEnableStrictFieldChecking(false); + } + } + + static class EntityWithoutID { private String attr0; @@ -648,6 +685,20 @@ public class MappingCouchbaseConverterTests { } } + static class AnnotatedEntity{ + @Id private String uuid; + @Field private String annotatedField; + private String nonAnnotatedField; + + public AnnotatedEntity(){ + this.uuid = java.util.UUID.randomUUID().toString(); + this.annotatedField = "Annotated Property"; + this.nonAnnotatedField = "Non Annotated Property"; + } + } + + + @WritingConverter public static enum BigDecimalToStringConverter implements Converter { INSTANCE;