diff --git a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java index b91594d3..d9b22f16 100644 --- a/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java +++ b/src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,8 +47,9 @@ import org.springframework.data.couchbase.core.mapping.event.BeforeConvertEvent; import org.springframework.data.couchbase.core.mapping.event.BeforeDeleteEvent; import org.springframework.data.couchbase.core.mapping.event.BeforeSaveEvent; import org.springframework.data.couchbase.core.mapping.event.CouchbaseMappingEvent; +import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.BeanWrapper; +import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import java.util.ArrayList; import java.util.Collection; @@ -185,8 +186,9 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP Object readEntity = couchbaseConverter.read(entityClass, (CouchbaseDocument) translateDecode( (String) result.getValue(), converted)); - final BeanWrapper beanWrapper = BeanWrapper.create(readEntity, couchbaseConverter.getConversionService()); CouchbasePersistentEntity persistentEntity = mappingContext.getPersistentEntity(readEntity.getClass()); + final PersistentPropertyAccessor beanWrapper = getPropertyAccessor(persistentEntity.getPropertyAccessor(readEntity)); + if (persistentEntity.hasVersionProperty()) { beanWrapper.setProperty(persistentEntity.getVersionProperty(), result.getCas()); } @@ -286,10 +288,10 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP public void save(Object objectToSave, final PersistTo persistTo, final ReplicateTo replicateTo) { ensureNotIterable(objectToSave); - final BeanWrapper beanWrapper = BeanWrapper.create(objectToSave, couchbaseConverter.getConversionService()); CouchbasePersistentEntity persistentEntity = mappingContext.getPersistentEntity(objectToSave.getClass()); + final ConvertingPropertyAccessor accessor = getPropertyAccessor(objectToSave); final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty(); - final Long version = versionProperty != null ? beanWrapper.getProperty(versionProperty, Long.class) : null; + final Long version = versionProperty != null ? accessor.getProperty(versionProperty, Long.class) : null; maybeEmitEvent(new BeforeConvertEvent(objectToSave)); final CouchbaseDocument converted = new CouchbaseDocument(); @@ -315,7 +317,7 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP throw new OptimisticLockingFailureException("Saving document with version value failed: " + cas); } else { long newCas = casFuture.getCas(); - beanWrapper.setProperty(versionProperty, newCas); + accessor.setProperty(versionProperty, newCas); return true; } } @@ -336,12 +338,12 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP ensureNotIterable(objectToInsert); final CouchbasePersistentEntity persistentEntity = mappingContext.getPersistentEntity(objectToInsert.getClass()); - final BeanWrapper beanWrapper = BeanWrapper.create(objectToInsert, couchbaseConverter.getConversionService()); + final ConvertingPropertyAccessor accessor = getPropertyAccessor(objectToInsert); if (persistentEntity != null && persistentEntity.hasVersionProperty()) { - final Long version = beanWrapper.getProperty(persistentEntity.getVersionProperty(), Long.class); + final Long version = accessor.getProperty(persistentEntity.getVersionProperty(), Long.class); if (version == 0) { - beanWrapper.setProperty(persistentEntity.getVersionProperty(), 0); + accessor.setProperty(persistentEntity.getVersionProperty(), 0); } } @@ -362,7 +364,7 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP } if (result && persistentEntity.hasVersionProperty()) { - beanWrapper.setProperty(persistentEntity.getVersionProperty(), addFuture.getCas()); + accessor.setProperty(persistentEntity.getVersionProperty(), addFuture.getCas()); } return result; } @@ -381,10 +383,10 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP public void update(Object objectToUpdate, final PersistTo persistTo, final ReplicateTo replicateTo) { ensureNotIterable(objectToUpdate); - final BeanWrapper beanWrapper = BeanWrapper.create(objectToUpdate, couchbaseConverter.getConversionService()); - CouchbasePersistentEntity persistentEntity = mappingContext.getPersistentEntity(objectToUpdate.getClass()); + CouchbasePersistentEntity persistentEntity = mappingContext.getPersistentEntity(objectToUpdate.getClass()); + final ConvertingPropertyAccessor accessor = getPropertyAccessor(objectToUpdate); final CouchbasePersistentProperty versionProperty = persistentEntity.getVersionProperty(); - final Long version = versionProperty != null ? beanWrapper.getProperty(versionProperty, Long.class) : null; + final Long version = versionProperty != null ? accessor.getProperty(versionProperty, Long.class) : null; maybeEmitEvent(new BeforeConvertEvent(objectToUpdate)); final CouchbaseDocument converted = new CouchbaseDocument(); @@ -406,7 +408,7 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP throw new OptimisticLockingFailureException("Updating document with version value failed: " + cas); } else { long newCas = casFuture.getCas(); - beanWrapper.setProperty(versionProperty, newCas); + accessor.setProperty(versionProperty, newCas); return true; } } @@ -490,4 +492,12 @@ public class CouchbaseTemplate implements CouchbaseOperations, ApplicationEventP public CouchbaseClient getCouchbaseClient() { return client; } + + private final ConvertingPropertyAccessor getPropertyAccessor(Object source) { + + CouchbasePersistentEntity entity = mappingContext.getPersistentEntity(source.getClass()); + PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source); + + return new ConvertingPropertyAccessor(accessor, couchbaseConverter.getConversionService()); + } } 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 5c809fa5..f909fe4f 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 @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors. + * Copyright 2013-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; +import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.PreferredConstructor.Parameter; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.context.MappingContext; @@ -157,9 +158,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter getParameterProvider(entity, source, evaluator, parent); EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity); - R instance = instantiator.createInstance(entity, provider); - final BeanWrapper wrapper = BeanWrapper.create(instance, conversionService); - final R result = wrapper.getBean(); + final R instance = instantiator.createInstance(entity, provider); + final PersistentPropertyAccessor accessor = getPropertyAccessor(instance); entity.doWithProperties(new PropertyHandler() { @Override @@ -167,8 +167,8 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter if (!doesPropertyExistInSource(prop) || entity.isConstructorArgument(prop)) { return; } - Object obj = prop.isIdProperty() ? source.getId() : getValueInternal(prop, source, result); - wrapper.setProperty(prop, obj); + Object obj = prop.isIdProperty() ? source.getId() : getValueInternal(prop, source, instance); + accessor.setProperty(prop, obj); } private boolean doesPropertyExistInSource(final CouchbasePersistentProperty property) { @@ -180,12 +180,12 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter @Override public void doWithAssociation(final Association association) { CouchbasePersistentProperty inverseProp = association.getInverse(); - Object obj = getValueInternal(inverseProp, source, result); - wrapper.setProperty(inverseProp, obj); + Object obj = getValueInternal(inverseProp, source, instance); + accessor.setProperty(inverseProp, obj); } }); - return result; + return instance; } /** @@ -377,12 +377,12 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter throw new MappingException("No mapping metadata found for entity of type " + source.getClass().getName()); } - final BeanWrapper wrapper = BeanWrapper.create(source, conversionService); + final ConvertingPropertyAccessor accessor = getPropertyAccessor(source); final CouchbasePersistentProperty idProperty = entity.getIdProperty(); final CouchbasePersistentProperty versionProperty = entity.getVersionProperty(); if (idProperty != null && target.getId() == null) { - String id = wrapper.getProperty(idProperty, String.class); + String id = accessor.getProperty(idProperty, String.class); target.setId(id); } target.setExpiration(entity.getExpiry()); @@ -394,7 +394,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter return; } - Object propertyObj = wrapper.getProperty(prop, prop.getType()); + Object propertyObj = accessor.getProperty(prop, prop.getType()); if (null != propertyObj) { if (!conversions.isSimpleType(propertyObj.getClass())) { writePropertyInternal(propertyObj, target, prop); @@ -410,7 +410,7 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter public void doWithAssociation(final Association association) { CouchbasePersistentProperty inverseProp = association.getInverse(); Class type = inverseProp.getType(); - Object propertyObj = wrapper.getProperty(inverseProp, type); + Object propertyObj = accessor.getProperty(inverseProp, type); if (null != propertyObj) { writePropertyInternal(propertyObj, target, inverseProp); } @@ -687,6 +687,14 @@ public class MappingCouchbaseConverter extends AbstractCouchbaseConverter return (R) getPotentiallyConvertedSimpleRead(value, rawType); } } + + private ConvertingPropertyAccessor getPropertyAccessor(Object source) { + + CouchbasePersistentEntity entity = mappingContext.getPersistentEntity(source.getClass()); + PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source); + + return new ConvertingPropertyAccessor(accessor, conversionService); + } /** * A property value provider for Couchbase documents. diff --git a/src/main/java/org/springframework/data/couchbase/repository/support/MappingCouchbaseEntityInformation.java b/src/main/java/org/springframework/data/couchbase/repository/support/MappingCouchbaseEntityInformation.java index c05cc67d..eb06c05d 100644 --- a/src/main/java/org/springframework/data/couchbase/repository/support/MappingCouchbaseEntityInformation.java +++ b/src/main/java/org/springframework/data/couchbase/repository/support/MappingCouchbaseEntityInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,10 +17,8 @@ package org.springframework.data.couchbase.repository.support; import org.springframework.data.couchbase.core.mapping.CouchbasePersistentEntity; -import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProperty; import org.springframework.data.couchbase.repository.query.CouchbaseEntityInformation; -import org.springframework.data.mapping.model.BeanWrapper; -import org.springframework.data.repository.core.support.AbstractEntityInformation; +import org.springframework.data.repository.core.support.PersistentEntityInformation; import java.io.Serializable; @@ -28,54 +26,18 @@ import java.io.Serializable; * Entity Information container. * * @author Michael Nitschinger + * @author Oliver Gierke */ public class MappingCouchbaseEntityInformation - extends AbstractEntityInformation + extends PersistentEntityInformation implements CouchbaseEntityInformation { - /** - * Contains the entity metadata. - */ - private final CouchbasePersistentEntity entityMetadata; - /** * Create a new Infomration container. * * @param entity the entity of the container. */ public MappingCouchbaseEntityInformation(final CouchbasePersistentEntity entity) { - super(entity.getType()); - entityMetadata = entity; - } - - /** - * Returns the ID of the entity. - * - * @param entity the entity from where to extract the ID from. - * @return the id of the entity. - */ - @Override - public ID getId(T entity) { - CouchbasePersistentProperty idProperty = entityMetadata.getIdProperty(); - - if (idProperty == null) { - return null; - } - - try { - return (ID) BeanWrapper.create(entity, null).getProperty(idProperty); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * Returns the ID type. - * - * @return the ID type. - */ - @Override - public Class getIdType() { - return (Class) entityMetadata.getIdProperty().getType(); + super(entity); } }