diff --git a/pom.xml b/pom.xml
index 41512eaee8..42d29d3933 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1288-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml
index fd36debedd..b2b9eca9d7 100644
--- a/spring-data-mongodb-cross-store/pom.xml
+++ b/spring-data-mongodb-cross-store/pom.xml
@@ -6,7 +6,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1288-SNAPSHOT
../pom.xml
@@ -48,7 +48,7 @@
org.springframework.data
spring-data-mongodb
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1288-SNAPSHOT
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index 28c91bc332..905fe9d556 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1288-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-log4j/pom.xml b/spring-data-mongodb-log4j/pom.xml
index dfe146ff96..b21d01a90b 100644
--- a/spring-data-mongodb-log4j/pom.xml
+++ b/spring-data-mongodb-log4j/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1288-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index 628b1ec633..219143daff 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -11,7 +11,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1288-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java
index d782492f50..f7a2471f27 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/CustomConversions.java
@@ -47,6 +47,7 @@
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToNamedMongoScriptCoverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.DBObjectToStringConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.NamedMongoScriptToDBObjectConverter;
+import org.springframework.data.mongodb.core.convert.MongoConverters.NumberToNumberConverterFactory;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigDecimalConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToBigIntegerConverter;
import org.springframework.data.mongodb.core.convert.MongoConverters.StringToURLConverter;
@@ -122,6 +123,7 @@ public CustomConversions(List> converters) {
toRegister.add(TermToStringConverter.INSTANCE);
toRegister.add(NamedMongoScriptToDBObjectConverter.INSTANCE);
toRegister.add(DBObjectToNamedMongoScriptCoverter.INSTANCE);
+ toRegister.add(NumberToNumberConverterFactory.INSTANCE);
toRegister.addAll(JodaTimeConverters.getConvertersToRegister());
toRegister.addAll(GeoConverters.getConvertersToRegister());
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java
index dfc796628d..303562d810 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConverters.java
@@ -19,16 +19,21 @@
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import org.bson.types.Code;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.TypeDescriptor;
+import org.springframework.core.convert.converter.ConditionalConverter;
import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.core.query.Term;
import org.springframework.data.mongodb.core.script.NamedMongoScript;
+import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;
import com.mongodb.BasicDBObject;
@@ -228,4 +233,50 @@ public DBObject convert(NamedMongoScript source) {
return builder.get();
}
}
+
+ /**
+ * {@link ConverterFactory} implementation using {@link NumberUtils} for number conversion and parsing. Additionally
+ * deals with {@link AtomicInteger} and {@link AtomicLong} by calling {@code get()} before performing the actual
+ * conversion.
+ *
+ * @author Christoph Strobl
+ * @since 1.9
+ */
+ @WritingConverter
+ public static enum NumberToNumberConverterFactory implements ConverterFactory, ConditionalConverter {
+
+ INSTANCE;
+
+ @Override
+ public Converter getConverter(Class targetType) {
+ return new NumberToNumber(targetType);
+ }
+
+ @Override
+ public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
+ return !sourceType.equals(targetType);
+ }
+
+ private final static class NumberToNumber implements Converter {
+
+ private final Class targetType;
+
+ public NumberToNumber(Class targetType) {
+ this.targetType = targetType;
+ }
+
+ @Override
+ public T convert(Number source) {
+
+ if (source instanceof AtomicInteger) {
+ return NumberUtils.convertNumberToTargetClass(((AtomicInteger) source).get(), this.targetType);
+ }
+ if (source instanceof AtomicLong) {
+ return NumberUtils.convertNumberToTargetClass(((AtomicLong) source).get(), this.targetType);
+ }
+
+ return NumberUtils.convertNumberToTargetClass(source, this.targetType);
+ }
+ }
+ }
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/NumberToNumberConverterFactoryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/NumberToNumberConverterFactoryUnitTests.java
new file mode 100644
index 0000000000..6957764bdd
--- /dev/null
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/NumberToNumberConverterFactoryUnitTests.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.mongodb.core.convert;
+
+import static org.hamcrest.core.Is.*;
+import static org.junit.Assert.*;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.springframework.data.mongodb.core.convert.MongoConverters.NumberToNumberConverterFactory;
+
+/**
+ * @author Christoph Strobl
+ */
+@RunWith(Parameterized.class)
+public class NumberToNumberConverterFactoryUnitTests {
+
+ public @Parameter(0) Number source;
+
+ public @Parameter(1) Number expected;
+
+ @Parameters
+ public static Collection parameters() {
+
+ Number[] longToInt = new Number[] { new Long(10), new Integer(10) };
+ Number[] atomicIntToInt = new Number[] { new AtomicInteger(10), new Integer(10) };
+ Number[] atomicIntToDouble = new Number[] { new AtomicInteger(10), new Double(10) };
+ Number[] atomicLongToInt = new Number[] { new AtomicLong(10), new Integer(10) };
+ Number[] atomicLongToLong = new Number[] { new AtomicLong(10), new Long(10) };
+
+ return Arrays. asList(longToInt, atomicIntToInt, atomicIntToDouble, atomicLongToInt, atomicLongToLong);
+ }
+
+ /**
+ * @see DATAMONGO-1288
+ */
+ @Test
+ public void convertsToTargetTypeCorrectly() {
+ assertThat(NumberToNumberConverterFactory.INSTANCE.getConverter(expected.getClass()).convert(source), is(expected));
+ }
+}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java
index 6099d0b2a8..feca9d76b9 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/UpdateMapperUnitTests.java
@@ -27,9 +27,11 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
import org.hamcrest.Matcher;
import org.hamcrest.collection.IsIterableContainingInOrder;
+import org.hamcrest.core.Is;
import org.hamcrest.core.IsEqual;
import org.junit.Before;
import org.junit.Test;
@@ -794,7 +796,7 @@ public void mapsUpdateWithBothReadingAndWritingConverterRegistered() {
}
/**
- * see DATAMONGO-1251
+ * @see DATAMONGO-1251
*/
@Test
public void mapsNullValueCorrectlyForSimpleTypes() {
@@ -810,7 +812,7 @@ public void mapsNullValueCorrectlyForSimpleTypes() {
}
/**
- * see DATAMONGO-1251
+ * @see DATAMONGO-1251
*/
@Test
public void mapsNullValueCorrectlyForJava8Date() {
@@ -826,7 +828,7 @@ public void mapsNullValueCorrectlyForJava8Date() {
}
/**
- * see DATAMONGO-1251
+ * @see DATAMONGO-1251
*/
@Test
public void mapsNullValueCorrectlyForCollectionTypes() {
@@ -842,7 +844,7 @@ public void mapsNullValueCorrectlyForCollectionTypes() {
}
/**
- * see DATAMONGO-1251
+ * @see DATAMONGO-1251
*/
@Test
public void mapsNullValueCorrectlyForPropertyOfNestedDocument() {
@@ -857,6 +859,34 @@ public void mapsNullValueCorrectlyForPropertyOfNestedDocument() {
assertThat($set.get("concreteValue.name"), nullValue());
}
+ /**
+ * @see DATAMONGO-1288
+ */
+ @Test
+ public void mapsAtomicIntegerToIntegerCorrectly() {
+
+ Update update = new Update().set("intValue", new AtomicInteger(10));
+ DBObject mappedUpdate = mapper.getMappedObject(update.getUpdateObject(),
+ context.getPersistentEntity(SimpleValueHolder.class));
+
+ DBObject $set = DBObjectTestUtils.getAsDBObject(mappedUpdate, "$set");
+ assertThat($set.get("intValue"), Is.