diff --git a/pom.xml b/pom.xml
index ff93af8ea6..72a16017f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 
 	<groupId>org.springframework.data</groupId>
 	<artifactId>spring-data-mongodb-parent</artifactId>
-	<version>2.0.0.BUILD-SNAPSHOT</version>
+	<version>2.0.0.DATAMONGO-1509-SNAPSHOT</version>
 	<packaging>pom</packaging>
 
 	<name>Spring Data MongoDB</name>
diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml
index 4a49168713..c1c263cbbc 100644
--- a/spring-data-mongodb-cross-store/pom.xml
+++ b/spring-data-mongodb-cross-store/pom.xml
@@ -6,7 +6,7 @@
 	<parent>
 		<groupId>org.springframework.data</groupId>
 		<artifactId>spring-data-mongodb-parent</artifactId>
-		<version>2.0.0.BUILD-SNAPSHOT</version>
+		<version>2.0.0.DATAMONGO-1509-SNAPSHOT</version>
 		<relativePath>../pom.xml</relativePath>
 	</parent>
 
@@ -48,7 +48,7 @@
 		<dependency>
 			<groupId>org.springframework.data</groupId>
 			<artifactId>spring-data-mongodb</artifactId>
-			<version>2.0.0.BUILD-SNAPSHOT</version>
+			<version>2.0.0.DATAMONGO-1509-SNAPSHOT</version>
 		</dependency>
 
 		<!-- reactive -->
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index 750ed23aa8..777490f61a 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -13,7 +13,7 @@
 	<parent>
 		<groupId>org.springframework.data</groupId>
 		<artifactId>spring-data-mongodb-parent</artifactId>
-		<version>2.0.0.BUILD-SNAPSHOT</version>
+		<version>2.0.0.DATAMONGO-1509-SNAPSHOT</version>
 		<relativePath>../pom.xml</relativePath>
 	</parent>
 
diff --git a/spring-data-mongodb-log4j/pom.xml b/spring-data-mongodb-log4j/pom.xml
index 50d0a6454a..4335e584fc 100644
--- a/spring-data-mongodb-log4j/pom.xml
+++ b/spring-data-mongodb-log4j/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>org.springframework.data</groupId>
 		<artifactId>spring-data-mongodb-parent</artifactId>
-		<version>2.0.0.BUILD-SNAPSHOT</version>
+		<version>2.0.0.DATAMONGO-1509-SNAPSHOT</version>
 		<relativePath>../pom.xml</relativePath>
 	</parent>
 
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index c8151d6665..6b8ea508bd 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -11,7 +11,7 @@
 	<parent>
 		<groupId>org.springframework.data</groupId>
 		<artifactId>spring-data-mongodb-parent</artifactId>
-		<version>2.0.0.BUILD-SNAPSHOT</version>
+		<version>2.0.0.DATAMONGO-1509-SNAPSHOT</version>
 		<relativePath>../pom.xml</relativePath>
 	</parent>
 
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 eb01d1dd8e..d3585d0569 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
@@ -359,20 +359,20 @@ public void write(final Object obj, final Bson bson) {
 			return;
 		}
 
-		Class<?> entityType = obj.getClass();
-		boolean handledByCustomConverter = conversions.getCustomWriteTarget(entityType, Document.class) != null;
+		Class<?> entityType = ClassUtils.getUserClass(obj.getClass());
 		TypeInformation<? extends Object> type = ClassTypeInformation.from(entityType);
 
-		if (!handledByCustomConverter && !(bson instanceof Collection)) {
-			typeMapper.writeType(type, bson);
-		}
-
 		Object target = obj instanceof LazyLoadingProxy ? ((LazyLoadingProxy) obj).getTarget() : obj;
 
 		writeInternal(target, bson, type);
 		if (asMap(bson).containsKey("_is") && asMap(bson).get("_id") == null) {
 			removeFromMap(bson, "_id");
 		}
+
+		boolean handledByCustomConverter = conversions.getCustomWriteTarget(entityType, Document.class) != null;
+		if (!handledByCustomConverter && !(bson instanceof Collection)) {
+			typeMapper.writeType(type, bson);
+		}
 	}
 
 	/**
@@ -529,12 +529,12 @@ protected void writePropertyInternal(Object obj, Bson bson, MongoPersistentPrope
 
 		Object existingValue = accessor.get(prop);
 		Document document = existingValue instanceof Document ? (Document) existingValue : new Document();
-		addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, document);
 
 		MongoPersistentEntity<?> entity = isSubtype(prop.getType(), obj.getClass())
 				? mappingContext.getPersistentEntity(obj.getClass()) : mappingContext.getPersistentEntity(type);
 
 		writeInternal(obj, document, entity);
+		addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, document);
 		accessor.put(prop, document);
 	}
 
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DocumentTestUtils.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DocumentTestUtils.java
index 5331467535..f6c0f83846 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DocumentTestUtils.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/DocumentTestUtils.java
@@ -18,6 +18,7 @@
 import static org.hamcrest.Matchers.*;
 import static org.junit.Assert.*;
 
+import java.util.Iterator;
 import java.util.List;
 
 import org.bson.Document;
@@ -80,4 +81,23 @@ public static <T> T getTypedValue(Document source, String key, Class<T> type) {
 
 		return (T) value;
 	}
+
+	public static void assertTypeHint(Document document, Class<?> type) {
+		assertTypeHint(document, type.getName());
+	}
+
+	public static void assertTypeHint(Document document, String expectedTypeString) {
+
+		Iterator<String> keyIterator = document.keySet().iterator();
+		while (keyIterator.hasNext()) {
+			String key = keyIterator.next();
+			if (key.equals("_class")) {
+				assertThat((String) document.get(key), is(equalTo(expectedTypeString)));
+				assertThat(keyIterator.hasNext(), is(false));
+				return;
+			}
+		}
+
+		fail(String.format("Expected to find type info %s in %s.", document, expectedTypeString));
+	}
 }
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
index aca1cab1ac..0c198ede3b 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MongoTemplateTests.java
@@ -44,6 +44,7 @@
 import org.joda.time.DateTime;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -3468,6 +3469,22 @@ public void onBeforeSave(BeforeSaveEvent<Document> event) {
 		assertThat(document.id, is(notNullValue()));
 	}
 
+
+	/**
+	 * @see DATAMONGO-1509
+	 */
+	@Test
+	public void findsByGnericNestedListElements() {
+
+		List<Model> modelList = Arrays.<Model>asList(new ModelA("value"));
+		DocumentWithCollection dwc = new DocumentWithCollection(modelList);
+
+		template.insert(dwc);
+
+		Query query = query(where("models").is(modelList));
+		assertThat(template.findOne(query, DocumentWithCollection.class), is(equalTo(dwc)));
+	}
+
 	static class TypeWithNumbers {
 
 		@Id String id;
@@ -3547,6 +3564,7 @@ static class DocumentWithDBRefCollection {
 		@org.springframework.data.mongodb.core.mapping.DBRef(lazy = true) public Map<String, Sample> lazyDbRefAnnotatedMap;
 	}
 
+	@EqualsAndHashCode
 	static class DocumentWithCollection {
 
 		@Id String id;
@@ -3599,6 +3617,7 @@ static interface Model {
 		String id();
 	}
 
+	@EqualsAndHashCode
 	static class ModelA implements Model {
 
 		@Id String id;
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 75b65ff869..adff1b3336 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
@@ -526,6 +526,9 @@ public void maybeConvertHandlesNullValuesCorrectly() {
 		assertThat(converter.convertToMongoType(null), is(nullValue()));
 	}
 
+	/**
+	 * @see DATAMONGO-1509
+	 */
 	@Test
 	public void writesGenericTypeCorrectly() {
 
@@ -537,7 +540,7 @@ public void writesGenericTypeCorrectly() {
 		converter.write(type, result);
 
 		org.bson.Document content = (org.bson.Document) result.get("content");
-		assertThat(content.get("_class"), is(notNullValue()));
+		assertTypeHint(content, Address.class);
 		assertThat(content.get("city"), is(notNullValue()));
 	}
 
@@ -1272,6 +1275,7 @@ public void eagerlyReturnsDBRefObjectIfTargetAlreadyIsOne() {
 
 	/**
 	 * @see DATAMONGO-523
+	 * @see DATAMONGO-1509
 	 */
 	@Test
 	public void considersTypeAliasAnnotation() {
@@ -1282,9 +1286,7 @@ public void considersTypeAliasAnnotation() {
 		org.bson.Document result = new org.bson.Document();
 		converter.write(aliased, result);
 
-		Object type = result.get("_class");
-		assertThat(type, is(notNullValue()));
-		assertThat(type.toString(), is("_"));
+		assertTypeHint(result, "_");
 	}
 
 	/**
@@ -1409,6 +1411,7 @@ public void writesProjectingTypeCorrectly() {
 	/**
 	 * @see DATAMONGO-812
 	 * @see DATAMONGO-893
+	 * @see DATAMONGO-1509
 	 */
 	@Test
 	public void convertsListToBasicDBListAndRetainsTypeInformationForComplexObjects() {
@@ -1424,7 +1427,7 @@ public void convertsListToBasicDBListAndRetainsTypeInformationForComplexObjects(
 
 		List<Object> dbList = (List<Object>) result;
 		assertThat(dbList, hasSize(1));
-		assertThat(getTypedValue(getAsDocument(dbList, 0), "_class", String.class), equalTo(Address.class.getName()));
+		assertTypeHint(getAsDocument(dbList, 0), Address.class);
 	}
 
 	/**
@@ -1444,6 +1447,7 @@ public void convertsListToBasicDBListWithoutTypeInformationForSimpleTypes() {
 
 	/**
 	 * @see DATAMONGO-812
+	 * @see DATAMONGO-1509
 	 */
 	@Test
 	public void convertsArrayToBasicDBListAndRetainsTypeInformationForComplexObjects() {
@@ -1458,7 +1462,7 @@ public void convertsArrayToBasicDBListAndRetainsTypeInformationForComplexObjects
 
 		List<Object> dbList = (List<Object>) result;
 		assertThat(dbList, hasSize(1));
-		assertThat(getTypedValue(getAsDocument(dbList, 0), "_class", String.class), equalTo(Address.class.getName()));
+		assertTypeHint(getAsDocument(dbList, 0), Address.class);
 	}
 
 	/**
@@ -1802,6 +1806,7 @@ public void shouldIncludeTextScorePropertyWhenReading() {
 
 	/**
 	 * @see DATAMONGO-1001
+	 * @see DATAMONGO-1509
 	 */
 	@Test
 	public void shouldWriteCglibProxiedClassTypeInformationCorrectly() {
@@ -1814,7 +1819,7 @@ public void shouldWriteCglibProxiedClassTypeInformationCorrectly() {
 		org.bson.Document document = new org.bson.Document();
 		converter.write(proxied, document);
 
-		assertThat(document.get("_class"), is((Object) GenericType.class.getName()));
+		assertTypeHint(document, GenericType.class);
 	}
 
 	/**