Fixed two issues with Mongo entity gen
diff --git a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoEntityGenerator.java b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoEntityGenerator.java
index 380b0a9..47dd874 100644
--- a/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoEntityGenerator.java
+++ b/tools/org.eclipse.persistence.tools.gen.nosql/src/org/eclipse/persistence/tools/gen/nosql/mongo/MongoEntityGenerator.java
@@ -59,9 +59,9 @@
 import org.eclipse.persistence.tools.utility.collection.ListTools;
 
 /**
- * This class is an entry point for dynamic entity xml and source generation for
- * MongoDB. It also provides API for discovering metadata (table names, etc) and generating
- * EclipseLink-JPA NoSql, mapping files.
+ * This class is an entry point for dynamic entity xml and source generation for MongoDB. It also
+ * provides API for discovering metadata (table names, etc) and generating EclipseLink-JPA NoSql,
+ * mapping files.
  * <p>
  * Provisional API: This interface is part of an interim API that is still under development and
  * expected to change significantly before reaching stability. It is available at this early stage
@@ -90,9 +90,9 @@
 	 * @param host the MongoDB network host.
 	 * @param port the port of the Mongo database.
 	 * @param dbName the name of the Mongo database.
-	 * @param rowSampleSize number of rows in each collection to sample to determine the
-	 * 		  table structure.  Since not all rows may have all possible values explicitly
-	 * 		  defined, it's important to use a sufficient sample size.
+	 * @param rowSampleSize number of rows in each collection to sample to determine the table
+	 * structure. Since not all rows may have all possible values explicitly defined, it's important
+	 * to use a sufficient sample size.
 	 *
 	 * @throws MongoException
 	 * @throws UnknownHostException
@@ -117,6 +117,7 @@
 	 * @return {@link List} of {@link CollectionDescriptor}s.
 	 */
 	private List<CollectionDescriptor> buildCollectionDescriptors(Collection<String> collectionNames) {
+
 		List<CollectionDescriptor> collectionDescriptors = new LinkedList<CollectionDescriptor>();
 
 		for (String collectionName : collectionNames) {
@@ -129,102 +130,53 @@
 	}
 
 	/**
-	 * Updates the {@link CollectionDescriptor}s associated with the provided
-	 * {@link CollectionDescriptor}.
+	 * Generates a {@link String} representation of an eclipselink-orm.xml descriptor based
+	 * on the provided MongoDB {@link CollectionDescriptor} definitions.
 	 *
-	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
+	 * @param collectionDescriptors the MongoDB collections to generate entities from.
+	 * @param packageName the package name to qualify all generated entities for.
+	 *
+	 * @return a {@link String} representation of the eclipselink-orm.xml.
 	 */
-	private void updateColumnDescriptors(CollectionDescriptor collectionDescriptor) {
-		// Read the collection from the database
-		DBCollection collection = this.database.getCollection(collectionDescriptor.getName());
+	private ExternalORMConfiguration generate(List<CollectionDescriptor> collectionDescriptors,
+	                                          String packageName) {
 
-		// Read a sampling of the rows to determine the super set of column keys
-		// that are in the collection.
-		DBCursor cursor = collection.find().limit(this.rowSampleSize);
-		for ( ;cursor.hasNext();) {
-			DBObject row = cursor.next();
-			updateCollectionDescriptor(collectionDescriptor, row);
+		try {
+			// Create a new orm.xml metadata model.
+			ExternalORMConfiguration config = new ORMRepository().buildORMConfiguration(null, ORMDocumentType.ECLIPELINK_2_6);
+
+			// track all entity names being used.
+			Set<String> allEntityNames = new HashSet<String>();
+
+			// Iterate over all collection descriptors and create an entity and associated mapping for them.
+			for (CollectionDescriptor collection : collectionDescriptors) {
+
+				// add an entity with a unique name
+				String collectionName = collection.getName();
+				String entityName = uniqueJavaClassName(collectionName, packageName, allEntityNames);
+				ExternalEntity exEntity = config.addEntity(entityName);
+
+				// access type is virtual
+				exEntity.setAccessType(AccessType.VIRTUAL);
+
+				// Configure NoSql settings
+				ExternalNoSql noSqlDesc = exEntity.addNoSql();
+				noSqlDesc.setDataFormat(DataFormatType.MAPPED);
+				noSqlDesc.setDataType(collectionName);
+
+				// add mappings
+				generateMappings(exEntity, collection, packageName, config, allEntityNames);
+			}
+
+			// Generate a default, read all query for all entities
+			generateQueries(config);
+
+			return config;
 		}
-
-	}
-
-	/**
-	 * Generates a set of EclipseLink, java entity files mapped to the underlying Mongo
-	 * database for the given <code>collectionNames</code>.
-	 *
-	 * @param collectionNames names of the Mongo collections to generate entities for.
-	 * @param packageName java package to use for the generated code.
-	 * @param baseDirectory the base directory to use for the generated code.
-	 * @param type the access type to use (method versus field annotations).
-	 * @param characterEncoding the type of character encoding to use (e.g. "UTF-8").
-	 *
-	 * @throws Exception
-	 */
-	public void generateSource(Collection<String> collectionNames, String packageName,
-													  File baseDirectory, AccessType type,
-													  String characterEncoding) throws Exception {
-		// Create metadata descriptors for the specified collections.
-		List<CollectionDescriptor> collectionDescriptors = buildCollectionDescriptors(collectionNames);
-		ExternalORMConfiguration config = generate(collectionDescriptors, packageName);
-
-		// Ensure that the provided gen directory and package folders exists
-		File packageDirectory = new File(baseDirectory, packageName.replace('.', '/') + "/");
-		packageDirectory.mkdirs();
-
-		// Build up the velocity generator
-		Properties vep = new Properties();
-		vep.setProperty("resource.loader", "class");
-		vep.setProperty("class.resource.loader.class",
-					    "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
-		VelocityEngine ve = new VelocityEngine();
-	    ve.init(vep);
-
-	    // Generate source for entities
-	    for (ExternalEntity entity : config.entities()) {
-	    	generateSource(entity, type, "entity.java.vm", packageName, packageDirectory, ve, characterEncoding);
-	    }
-
-	    // Generate source for embeddables
-	    for (ExternalEmbeddable entity : config.embeddables()) {
-	    	generateSource(entity, type, "embeddable.java.vm", packageName, packageDirectory, ve, characterEncoding);
-	    }
-	}
-
-	/**
-	 *  Generates the entity source file for the provided mapping metadata.
-	 *
-	 * @param entity the metadata representation of the entity.
-	 * @param accessType the {@link AccessType} to use (method or field) for annotations.
-	 * @param templateName the source gen template to use (embeddable, entity, etc).
-	 * @param packageName the package name to use.
-	 * @param packageDirectory the directory to generate the source file in.
-	 * @param ve the velocity engine to use.
-	 * @param characterEncoding the type of character encoding to use.
-	 *
-	 * @throws Exception
-	 */
-	private void generateSource(ExternalEmbeddable entity, AccessType accessType,
-														 String templateName, String packageName,
-														 File packageDirectory, VelocityEngine ve,
-														 String characterEncoding) throws Exception {
-		VelocityContext context = new VelocityContext();
-		context.put("entity", entity);
-		context.put("mappings", ListTools.list(entity.mappings()));
-		context.put("packageName", packageName);
-		context.put("accessType", accessType);
-		StringWriter w = new StringWriter();
-		ve.mergeTemplate(templateName, context, w);
-
-		String fileContent = w.toString();
-
-		File javaFile = new File(packageDirectory, entity.getClassShortName() + ".java");
-
-		byte[] content = fileContent.getBytes(characterEncoding);
-		javaFile.createNewFile();
-		FileOutputStream writer = new FileOutputStream(javaFile);
-		writer.write(content);
-		writer.flush();
-		writer.close();
+		catch (IOException e) {
+			// Never happens
+			return null;
+		}
 	}
 
 	/**
@@ -236,25 +188,33 @@
 	 * @param columnName the name of the column.
 	 * @param javaColumnName the java identifier name to use for the column.
 	 */
-	private void generateLeafMapping(ExternalEmbeddable exEntity, LeafColumnDescriptor column,
-															  String columnName, String javaColumnName) {
+	private void generateLeafMapping(ExternalEmbeddable exEntity,
+	                                 LeafColumnDescriptor column,
+	                                 String columnName,
+	                                 String javaColumnName) {
+
 		ExternalColumnMapping mapping;
+
 		// If this is a list-type column, then a collection based mapping is required.
 		if (column.isList()) {
-			mapping = exEntity.addElementCollectionMapping(columnName);
-			((ExternalElementCollectionMapping)mapping).
-				setTargetClassName(column.getColumnType().getName());
+			mapping = exEntity.addElementCollectionMapping(javaColumnName);
+			((ExternalElementCollectionMapping) mapping).setTargetClassName(column.getColumnType().getName());
 			mapping.setAttributeType(Vector.class.getName());
-		} else {
+		}
+		else {
+
 			// special case where _id is reserved as a pk name in mongo.
 			// this is always intended to be an ID mapping.
 			if (columnName.equals("_id")) {
 				mapping = exEntity.addIdMapping(javaColumnName);
-			} else {
+			}
+			else {
 				mapping = exEntity.addBasicMapping(javaColumnName);
 			}
+
 			mapping.setAttributeType(column.getColumnType().getName());
 		}
+
 		mapping.setNoSqlField(columnName);
 	}
 
@@ -267,17 +227,22 @@
 	 * @param config the orm configuration.
 	 * @param allEntityNames a {@link Set} of all of the entity names already in use.
 	 */
-	private void generateMappings(ExternalEmbeddable exEntity, CollectionDescriptor collection, String packageName,
-														   ExternalORMConfiguration config, Set<String> allEntityNames) {
+	private void generateMappings(ExternalEmbeddable exEntity,
+	                              CollectionDescriptor collection,
+	                              String packageName,
+	                              ExternalORMConfiguration config,
+	                              Set<String> allEntityNames) {
+
 		for (ColumnDescriptor column : collection.columns()) {
 			String columnName = column.getColumnName();
 			String javaColumnName = NameTools.javaNameFromDatabaseName(columnName);
+			javaColumnName = jpaAnnotationToMappingName(javaColumnName);
+
 			if (column instanceof LeafColumnDescriptor) {
-				generateLeafMapping(exEntity, (LeafColumnDescriptor)column,
-									columnName, javaColumnName);
-			} else if (column instanceof NestedColumnDescriptor) {
-				generateNestedMapping(exEntity, config, packageName, allEntityNames,
-									  (NestedColumnDescriptor)column, columnName, javaColumnName);
+				generateLeafMapping(exEntity, (LeafColumnDescriptor) column, columnName, javaColumnName);
+			}
+			else if (column instanceof NestedColumnDescriptor) {
+				generateNestedMapping(exEntity, config, packageName, allEntityNames, (NestedColumnDescriptor) column, columnName, javaColumnName);
 			}
 		}
 	}
@@ -293,13 +258,20 @@
 	 * @param columnName the name of the column.
 	 * @param javaColumnName the java identifier name for the column.
 	 */
-	private void generateNestedMapping(ExternalEmbeddable exEntity,ExternalORMConfiguration config, String packageName,
-									   Set<String> allEntityNames, NestedColumnDescriptor column, String columnName, String javaColumnName) {
+	private void generateNestedMapping(ExternalEmbeddable exEntity,
+	                                   ExternalORMConfiguration config,
+	                                   String packageName,
+	                                   Set<String> allEntityNames,
+	                                   NestedColumnDescriptor column,
+	                                   String columnName,
+	                                   String javaColumnName) {
+
 		// Create the embeddable for the nested value
 		String embeddableName = uniqueJavaClassName(columnName, packageName, allEntityNames);
 		ExternalEmbeddable embeddable = config.addEmbeddable(embeddableName);
 		embeddable.addNoSql().setDataFormat(DataFormatType.MAPPED);
 		embeddable.setAccessType(AccessType.VIRTUAL);
+
 		// generate mappings for the embeddable
 		generateMappings(embeddable, column.getColumnDescriptor(), packageName, config, allEntityNames);
 
@@ -330,53 +302,92 @@
 			ExternalNamedQuery query = config.addNamedQuery(entityName + ".findAll");
 			char identifier = Character.toLowerCase(entityName.charAt(0));
 			query.setQuery("select " + identifier + " from " + entityName + " "  + identifier);
-
 		}
 	}
 
 	/**
-	 * Generates a {@link String} representation of an eclipselink-orm.xml descriptor based
-	 * on the provided MongoDB {@link CollectionDescriptor} definitions.
+	 * Generates a set of EclipseLink, java entity files mapped to the underlying Mongo
+	 * database for the given <code>collectionNames</code>.
 	 *
-	 * @param collectionDescriptors the MongoDB collections to generate entities from.
-	 * @param packageName the package name to qualify all generated entities for.
+	 * @param collectionNames names of the Mongo collections to generate entities for.
+	 * @param packageName java package to use for the generated code.
+	 * @param baseDirectory the base directory to use for the generated code.
+	 * @param type the access type to use (method versus field annotations).
+	 * @param characterEncoding the type of character encoding to use (e.g. "UTF-8").
 	 *
-	 * @return a {@link String} representation of the eclipselink-orm.xml.
+	 * @throws Exception
 	 */
-	private ExternalORMConfiguration generate(List<CollectionDescriptor> collectionDescriptors, String packageName) {
-		try {
-			// Create a new orm.xml metadata model.
-			ExternalORMConfiguration config = new ORMRepository().buildORMConfiguration(null, ORMDocumentType.ECLIPELINK_2_6);
-			// track all entity names being used.
-			Set<String> allEntityNames = new HashSet<String>();
-			// Iterate over all collection descriptors and create an entity and associated mapping for them.
-			for (CollectionDescriptor collection : collectionDescriptors) {
-				// add an entity with a unique name
-				String collectionName = collection.getName();
-				String entityName = uniqueJavaClassName(collectionName, packageName, allEntityNames);
-				ExternalEntity exEntity = config.addEntity(entityName);
-				// access type is virtual
-				exEntity.setAccessType(AccessType.VIRTUAL);
-				// Configure NoSql settings
-				ExternalNoSql noSqlDesc = exEntity.addNoSql();
-				noSqlDesc.setDataFormat(DataFormatType.MAPPED);
-				noSqlDesc.setDataType(collectionName);
-				// add mappings
-				generateMappings(exEntity, collection, packageName, config, allEntityNames);
-			}
+	public void generateSource(Collection<String> collectionNames,
+	                           String packageName,
+	                           File baseDirectory,
+	                           AccessType type,
+	                           String characterEncoding) throws Exception {
 
-			// Generate a default, read all query for all entities
-			generateQueries(config);
+		// Create metadata descriptors for the specified collections.
+		List<CollectionDescriptor> collectionDescriptors = buildCollectionDescriptors(collectionNames);
+		ExternalORMConfiguration config = generate(collectionDescriptors, packageName);
 
-			return config;
+		// Ensure that the provided gen directory and package folders exists
+		File packageDirectory = new File(baseDirectory, packageName.replace('.', '/') + "/");
+		packageDirectory.mkdirs();
+
+		// Build up the velocity generator
+		Properties vep = new Properties();
+		vep.setProperty("resource.loader", "class");
+		vep.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
+		VelocityEngine ve = new VelocityEngine();
+		ve.init(vep);
+
+		// Generate source for entities
+		for (ExternalEntity entity : config.entities()) {
+			generateSource(entity, type, "entity.java.vm", packageName, packageDirectory, ve, characterEncoding);
 		}
-		catch (IOException e) {
-			// Never happens
-			return null;
+
+		// Generate source for embeddables
+		for (ExternalEmbeddable entity : config.embeddables()) {
+			generateSource(entity, type, "embeddable.java.vm", packageName, packageDirectory, ve, characterEncoding);
 		}
 	}
 
 	/**
+	 *  Generates the entity source file for the provided mapping metadata.
+	 *
+	 * @param entity the metadata representation of the entity.
+	 * @param accessType the {@link AccessType} to use (method or field) for annotations.
+	 * @param templateName the source gen template to use (embeddable, entity, etc).
+	 * @param packageName the package name to use.
+	 * @param packageDirectory the directory to generate the source file in.
+	 * @param ve the velocity engine to use.
+	 * @param characterEncoding the type of character encoding to use.
+	 *
+	 * @throws Exception
+	 */
+	private void generateSource(ExternalEmbeddable entity, AccessType accessType,
+														 String templateName, String packageName,
+														 File packageDirectory, VelocityEngine ve,
+														 String characterEncoding) throws Exception {
+
+		VelocityContext context = new VelocityContext();
+		context.put("entity", entity);
+		context.put("mappings", ListTools.list(entity.mappings()));
+		context.put("packageName", packageName);
+		context.put("accessType", accessType);
+		StringWriter w = new StringWriter();
+		ve.mergeTemplate(templateName, context, w);
+
+		String fileContent = w.toString();
+
+		File javaFile = new File(packageDirectory, entity.getClassShortName() + ".java");
+
+		byte[] content = fileContent.getBytes(characterEncoding);
+		javaFile.createNewFile();
+		FileOutputStream writer = new FileOutputStream(javaFile);
+		writer.write(content);
+		writer.flush();
+		writer.close();
+	}
+
+	/**
 	 * Creates an eclipselink-orm.xml descriptor mapping the provided <code>collectionNames</code>
 	 * as EclipseLink dynamic entities.
 	 *
@@ -385,6 +396,7 @@
 	 * @return a {@link String} representation of the eclipselink-orm.xml.
 	 */
 	public String generateXML(Collection<String> collectionNames, String packageName) {
+
 		// Create metadata descriptors for the specified collections.
 		List<CollectionDescriptor> collectionDescriptors = buildCollectionDescriptors(collectionNames);
 
@@ -401,20 +413,27 @@
 	 * @param value the row value of the column.
 	 */
 	private void handleLeafColumn(CollectionDescriptor collectionDescriptor,
-													   String columnName, Object value) {
-		LeafColumnDescriptor columnDescriptor = (LeafColumnDescriptor)collectionDescriptor.getColumn(columnName);
+	                              String columnName,
+	                              Object value) {
+
+		LeafColumnDescriptor columnDescriptor = (LeafColumnDescriptor) collectionDescriptor.getColumn(columnName);
+
 		if (columnDescriptor == null) {
 			columnDescriptor = collectionDescriptor.addLeafColumn(columnName);
 		}
+
 		Class<?> valueClass = value.getClass();
+
 		// Special case for an id-type column. If one is not explicitly defined,
 		// Mongo auto-generates one and uses the noted class for the type. This
 		// should be considered a String in java.
 		valueClass = valueClass.getName().equals("org.bson.types.ObjectId") ? String.class : valueClass;
+
 		// if the column type isn't consistent, just use Object as the type.
 		if (columnDescriptor.getColumnType() == null) {
 			columnDescriptor.setColumnType(valueClass);
-		} else if (columnDescriptor.getColumnType() != valueClass) {
+		}
+		else if (columnDescriptor.getColumnType() != valueClass) {
 			columnDescriptor.setColumnType(Object.class);
 		}
 	}
@@ -427,47 +446,58 @@
 	 * @param columnName the name of the column to update.
 	 * @param value the row value, or in this case the list value row.
 	 */
-	private void handleListColumn(CollectionDescriptor collectionDescriptor, String columnName,
-																		    	Object value) {
+	private void handleListColumn(CollectionDescriptor collectionDescriptor,
+	                              String columnName,
+	                              BasicDBList listValue) {
+
 		ColumnDescriptor columnDescriptor = collectionDescriptor.getColumn(columnName);
-		BasicDBList listValue = (BasicDBList)value;
+
 		if (listValue.size() > 0) {
+
 			Iterator<?> listValues = listValue.listIterator();
 			Object valueFromList = listValues.next();
+
 			// Handle nested list
 			if (valueFromList instanceof BasicDBObject) {
 				NestedColumnDescriptor nestedColumnDesc;
+
 				if (columnDescriptor == null) {
-					nestedColumnDesc  = collectionDescriptor.addNestedColumn(columnName);
-				} else {
-					nestedColumnDesc = (NestedColumnDescriptor)columnDescriptor;
+					nestedColumnDesc = collectionDescriptor.addNestedColumn(columnName);
 				}
-				nestedColumnDesc.setList(true);
-				updateCollectionDescriptor(nestedColumnDesc.getColumnDescriptor(), (DBObject)valueFromList);
-				// Iterate over subsequent nested values to ensure the superset of all columns keys
-				// are included
-				for (;listValues.hasNext();) {
-					valueFromList = listValues.next();
-					updateCollectionDescriptor(nestedColumnDesc.getColumnDescriptor(), (DBObject)valueFromList);
+				else {
+					nestedColumnDesc = (NestedColumnDescriptor) columnDescriptor;
 				}
 
+				nestedColumnDesc.setList(true);
+				updateCollectionDescriptor(nestedColumnDesc.getColumnDescriptor(), (DBObject) valueFromList);
+
+				// Iterate over subsequent nested values to ensure the superset of all columns keys
+				// are included
+				while (listValues.hasNext()) {
+					valueFromList = listValues.next();
+					updateCollectionDescriptor(nestedColumnDesc.getColumnDescriptor(), (DBObject) valueFromList);
+				}
 			}
 			// Handle leaf list
-			else {
+			else if (valueFromList != null) {
 				LeafColumnDescriptor leafColumnDescriptor;
+
 				if (columnDescriptor == null) {
-					leafColumnDescriptor  = collectionDescriptor.addLeafColumn(columnName);
-				} else {
-					leafColumnDescriptor = (LeafColumnDescriptor)columnDescriptor;
+					leafColumnDescriptor = collectionDescriptor.addLeafColumn(columnName);
+				}
+				else {
+					leafColumnDescriptor = (LeafColumnDescriptor) columnDescriptor;
 				}
 
 				leafColumnDescriptor.setList(true);
 				leafColumnDescriptor.setColumnType(valueFromList.getClass());
-				// Iterate over subsequent elements. If the element type isn't the same as the last, default to Object
-				// and break.
-				for (;listValues.hasNext();) {
+
+				// Iterate over subsequent elements. If the element type isn't the same as the last,
+				// default to Object and break.
+				while (listValues.hasNext()) {
 					valueFromList = listValues.next();
-					if (leafColumnDescriptor.getColumnType() != valueFromList.getClass()) {
+
+					if ((valueFromList != null) && (leafColumnDescriptor.getColumnType() != valueFromList.getClass())) {
 						leafColumnDescriptor.setColumnType(Object.class);
 						break;
 					}
@@ -485,9 +515,11 @@
 	 * @param value row value of the column, or in this case the nest row.
 	 */
 	private void handleNestedColumn(CollectionDescriptor collectionDescriptor,
-								   					   String columnName, Object value) {
+	                                String columnName,
+	                                Object value) {
+
 		NestedColumnDescriptor columnDescriptor =
-				(NestedColumnDescriptor)collectionDescriptor.getColumn(columnName);
+			(NestedColumnDescriptor) collectionDescriptor.getColumn(columnName);
 
 		if (columnDescriptor == null) {
 			columnDescriptor = collectionDescriptor.addNestedColumn(columnName);
@@ -496,14 +528,44 @@
 		updateCollectionDescriptor(columnDescriptor.getColumnDescriptor(), (DBObject)value);
 	}
 
+	private String jpaAnnotationToEntityName(String entityName) {
+
+		// Add "Entity" at the end of the entity name to prevent collision with
+		// @Entity, @MappedSuperclass and @Embeddable
+		if (entityName.equalsIgnoreCase("Entity")     ||
+		    entityName.equalsIgnoreCase("Embeddable") ||
+		    entityName.equalsIgnoreCase("MappedSuperclass")) {
+
+			entityName += "Entity";
+		}
+
+		return entityName;
+	}
+
+	private String jpaAnnotationToMappingName(String mappingName) {
+
+		// Add "Mapping" at the end of the entity name to prevent collision with
+		// @Basic, @ElementCollection, @Embedded and @Id
+		if (mappingName.equalsIgnoreCase("Id")       ||
+		    mappingName.equalsIgnoreCase("Basic")    ||
+		    mappingName.equalsIgnoreCase("Embedded") ||
+		    mappingName.equalsIgnoreCase("ElementCollection")) {
+
+			mappingName += "Mapping";
+		}
+
+		return mappingName;
+	}
+
 	/**
-	 * Returns the names of the Mongo collections on the specified
-	 * database.
+	 * Returns the names of the Mongo collections on the specified database.
 	 *
 	 * @return the name of the Mongo collections.
 	 */
 	public Set<String> listCollectionNames() {
+
 		Set<String> collectionNames = this.database.getCollectionNames();
+
 		// Remove the internal system.indexes table name
 		collectionNames.remove("system.indexes");
 
@@ -521,10 +583,14 @@
 	 * @return the unique, qualifed and singularised entity name.
 	 */
 	private String uniqueJavaClassName(String collectionName, String packageName, Set<String> allEntityNames) {
+
 		String entityName = StringUtil.singularise(NameTools.javaNameFromDatabaseName(collectionName, true));
-		if (!StringTools.isBlank(packageName)) {
+		entityName = jpaAnnotationToEntityName(entityName);
+
+		if (StringTools.isNotBlank(packageName)) {
 			entityName = packageName + "." + entityName;
 		}
+
 		entityName = NameTools.uniqueName(entityName, allEntityNames);
 		allEntityNames.add(entityName);
 
@@ -539,14 +605,18 @@
 	 * @param dbObject the row to infer columns from.
 	 */
 	private void updateCollectionDescriptor(CollectionDescriptor collectionDescriptor, DBObject dbObject) {
+
 		// iterate over all of the available names in the row.
 		for (String columnName : dbObject.keySet()) {
+
 			Object value = dbObject.get(columnName);
+
 			// if a column does not yet exist in our descriptor, add one.
 			if (value != null) {
+
 				// List type
 				if (value instanceof BasicDBList) {
-					handleListColumn(collectionDescriptor, columnName, value);
+					handleListColumn(collectionDescriptor, columnName, (BasicDBList) value);
 				}
 				// Single Nested
 				else if (value instanceof BasicDBObject) {
@@ -559,4 +629,24 @@
 			}
 		}
 	}
+
+	/**
+	 * Updates the {@link CollectionDescriptor}s associated with the provided
+	 * {@link CollectionDescriptor}.
+	 *
+	 * @param collectionDescriptor the {@link CollectionDescriptor} to update.
+	 */
+	private void updateColumnDescriptors(CollectionDescriptor collectionDescriptor) {
+
+		// Read the collection from the database
+		DBCollection collection = this.database.getCollection(collectionDescriptor.getName());
+
+		// Read a sampling of the rows to determine the super set of column keys
+		// that are in the collection.
+		DBCursor cursor = collection.find().limit(this.rowSampleSize);
+
+		for (DBObject row : cursor) {
+			updateCollectionDescriptor(collectionDescriptor, row);
+		}
+	}
 }
\ No newline at end of file