diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 359c4cd5d..a7e1e3605 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -346,13 +346,14 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } final BeanWrapper, Object> wrapper = BeanWrapper.create(obj, conversionService); - - // Write the ID final MongoPersistentProperty idProperty = entity.getIdProperty(); + if (!dbo.containsField("_id") && null != idProperty) { + boolean fieldAccessOnly = idProperty.usePropertyAccess() ? false : useFieldAccessOnly; + try { - Object id = wrapper.getProperty(idProperty, Object.class, useFieldAccessOnly); + Object id = wrapper.getProperty(idProperty, Object.class, fieldAccessOnly); dbo.put("_id", idMapper.convertId(id)); } catch (ConversionException ignored) { } @@ -366,7 +367,9 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return; } - Object propertyObj = wrapper.getProperty(prop, prop.getType(), useFieldAccessOnly); + boolean fieldAccessOnly = prop.usePropertyAccess() ? false : useFieldAccessOnly; + + Object propertyObj = wrapper.getProperty(prop, prop.getType(), fieldAccessOnly); if (null != propertyObj) { if (!conversions.isSimpleType(propertyObj.getClass())) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java index 03e91abac..d823cb171 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java @@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; import org.springframework.data.mapping.model.SimpleTypeHolder; +import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import com.mongodb.DBObject; @@ -46,6 +47,8 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope private static final Set> SUPPORTED_ID_TYPES = new HashSet>(); private static final Set SUPPORTED_ID_PROPERTY_NAMES = new HashSet(); + private static final Field CAUSE_FIELD; + static { SUPPORTED_ID_TYPES.add(ObjectId.class); SUPPORTED_ID_TYPES.add(String.class); @@ -53,6 +56,8 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope SUPPORTED_ID_PROPERTY_NAMES.add("id"); SUPPORTED_ID_PROPERTY_NAMES.add("_id"); + + CAUSE_FIELD = ReflectionUtils.findField(Throwable.class, "cause"); } /** @@ -155,4 +160,12 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope public boolean isVersionProperty() { return getField().isAnnotationPresent(Version.class); } + + /* + * (non-Javadoc) + * @see org.springframework.data.mongodb.core.mapping.MongoPersistentProperty#usePropertyAccess() + */ + public boolean usePropertyAccess() { + return CAUSE_FIELD.equals(getField()); + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java index d5e1d6533..6f523c347 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/MongoPersistentProperty.java @@ -80,4 +80,12 @@ public interface MongoPersistentProperty extends PersistentProperty extends BasicPersistentEntity implements diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index ef8eb2077..71026e308 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -918,7 +918,7 @@ public class MappingMongoConverterUnitTests { Object contacts = result.get("contacts"); assertThat(contacts, is(instanceOf(Collection.class))); assertThat(((Collection) contacts).size(), is(2)); - assertThat(((Collection) contacts), hasItem(nullValue())); + assertThat((Collection) contacts, hasItem(nullValue())); } /** @@ -1310,6 +1310,19 @@ public class MappingMongoConverterUnitTests { assertThat(type.toString(), is("_")); } + /** + * @see DATAMONGO-533 + */ + @Test + public void marshalsThrowableCorrectly() { + + ThrowableWrapper wrapper = new ThrowableWrapper(); + wrapper.throwable = new Exception(); + + DBObject dbObject = new BasicDBObject(); + converter.write(wrapper, dbObject); + } + static class GenericType { T content; } @@ -1498,6 +1511,11 @@ public class MappingMongoConverterUnitTests { String name; } + static class ThrowableWrapper { + + Throwable throwable; + } + private class LocalDateToDateConverter implements Converter { public Date convert(LocalDate source) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java index 92a1f2577..b1c26388f 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentPropertyUnitTests.java @@ -68,6 +68,16 @@ public class BasicMongoPersistentPropertyUnitTests { getPropertyFor(ReflectionUtils.findField(Person.class, "ssn")); } + /** + * @see DATAMONGO-553 + */ + @Test + public void usesPropertyAccessForThrowableCause() { + + MongoPersistentProperty property = getPropertyFor(ReflectionUtils.findField(Throwable.class, "cause")); + assertThat(property.usePropertyAccess(), is(true)); + } + private MongoPersistentProperty getPropertyFor(Field field) { return new BasicMongoPersistentProperty(field, null, entity, new SimpleTypeHolder()); }