diff --git a/src/main/java/com/couchbase/spring/core/convert/MappingCouchbaseConverter.java b/src/main/java/com/couchbase/spring/core/convert/MappingCouchbaseConverter.java index 253012bc..5a58134b 100644 --- a/src/main/java/com/couchbase/spring/core/convert/MappingCouchbaseConverter.java +++ b/src/main/java/com/couchbase/spring/core/convert/MappingCouchbaseConverter.java @@ -28,10 +28,13 @@ import com.couchbase.spring.core.mapping.CouchbasePersistentProperty; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.Field; + import org.codehaus.jackson.JsonEncoding; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.JsonParser; +import org.codehaus.jackson.JsonToken; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -66,13 +69,44 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter @Override public R read(Class type, ConvertedCouchbaseDocument doc) { + CouchbasePersistentEntity entity = mappingContext.getPersistentEntity(type); + + R decoded = null; + try { + decoded = type.getConstructor(String.class).newInstance(doc.getId()); + } catch(Exception e) { + throw new MappingException("Could not instantiate object while converting " + + doc.getId()); + } + JsonFactory jsonFactory = new JsonFactory(); try { JsonParser parser = jsonFactory.createJsonParser(doc.getValue()); + parser.nextToken(); + while(parser.nextToken() != JsonToken.END_OBJECT) { + String fieldname = parser.getCurrentName(); + parser.nextToken(); + CouchbasePersistentProperty property = entity.getPersistentProperty(fieldname); + if(property == null) { + continue; + } + Field field = type.getDeclaredField(property.getOriginalName()); + field.setAccessible(true); + + if(property.getType().equals(boolean.class)) { + field.set(decoded, parser.getValueAsBoolean()); + } else if(property.getType().equals(String.class)) { + field.set(decoded, parser.getText()); + } else { + throw new MappingException("Unknown type in JSON found: " + property.getType()); + } + } } catch(Exception e) { throw new MappingException("Could not read from JSON while converting " - + doc.getId()); + + doc.getId(), e); } + + return decoded; } @Override diff --git a/src/main/java/com/couchbase/spring/core/mapping/BasicCouchbasePersistentEntity.java b/src/main/java/com/couchbase/spring/core/mapping/BasicCouchbasePersistentEntity.java index ba34de13..941d7d84 100644 --- a/src/main/java/com/couchbase/spring/core/mapping/BasicCouchbasePersistentEntity.java +++ b/src/main/java/com/couchbase/spring/core/mapping/BasicCouchbasePersistentEntity.java @@ -60,4 +60,5 @@ public class BasicCouchbasePersistentEntity } return annotation.expiry(); } + } diff --git a/src/main/java/com/couchbase/spring/core/mapping/BasicCouchbasePersistentProperty.java b/src/main/java/com/couchbase/spring/core/mapping/BasicCouchbasePersistentProperty.java index b2db7d6b..252cd38e 100644 --- a/src/main/java/com/couchbase/spring/core/mapping/BasicCouchbasePersistentProperty.java +++ b/src/main/java/com/couchbase/spring/core/mapping/BasicCouchbasePersistentProperty.java @@ -76,5 +76,21 @@ public class BasicCouchbasePersistentProperty return annotation != null && StringUtils.hasText(annotation.value()) ? annotation.value() : field.getName(); } + + /** + * Return the name of the property. + * + * This overrides the default implementation to make sure that when + * the property is retrieved from a JSON document it can be found + * even when a alias is used. + */ + @Override + public String getName() { + return getFieldName(); + } + + public String getOriginalName() { + return name; + } } diff --git a/src/main/java/com/couchbase/spring/core/mapping/CouchbasePersistentProperty.java b/src/main/java/com/couchbase/spring/core/mapping/CouchbasePersistentProperty.java index cc99cd4c..536f3c33 100644 --- a/src/main/java/com/couchbase/spring/core/mapping/CouchbasePersistentProperty.java +++ b/src/main/java/com/couchbase/spring/core/mapping/CouchbasePersistentProperty.java @@ -35,4 +35,6 @@ public interface CouchbasePersistentProperty extends * custom annotation. */ String getFieldName(); + + String getOriginalName(); } diff --git a/src/test/java/com/couchbase/spring/core/Beer.java b/src/test/java/com/couchbase/spring/core/Beer.java index 56c18a41..44a9d5ad 100644 --- a/src/test/java/com/couchbase/spring/core/Beer.java +++ b/src/test/java/com/couchbase/spring/core/Beer.java @@ -65,5 +65,9 @@ public class Beer { public boolean getActive() { return active; } + + public String getId() { + return id; + } } diff --git a/src/test/java/com/couchbase/spring/core/CouchbaseTemplateTest.java b/src/test/java/com/couchbase/spring/core/CouchbaseTemplateTest.java index 09223929..993c88b6 100644 --- a/src/test/java/com/couchbase/spring/core/CouchbaseTemplateTest.java +++ b/src/test/java/com/couchbase/spring/core/CouchbaseTemplateTest.java @@ -94,6 +94,22 @@ public class CouchbaseTemplateTest { assertNull(client.get(id)); } + @Test + public void validfindById() { + String id = "beers:findme-stout"; + String name = "The Findme Stout"; + boolean active = true; + Beer beer = new Beer(id).setName(name).setActive(active); + template.save(beer); + + Beer found = template.findById(id, Beer.class); + assertNotNull(found); + assertEquals(id, found.getId()); + assertEquals(name, found.getName()); + assertEquals(active, found.getActive()); + + } + /** * A sample document with just an id and property. */