MongoDB: Supplemental - A complete Java Project - Part 2 - codecentric AG Blog

:

The previous part of this series was dealing with storing some medium complex documents to MongoDB. Now it is time to pull them out again. As so far we are only dealing with a single document at a time (and not with a list of documents) that should not be too complicated. When writing the document it was a major part to convert from the “business objects” (that do not know anything about MongoDB) into the JSON-representation required to store documents. This time we will obviously need to reverse this by converting from JSON-representation to our business objects. Ok, but first of all the document in question needs to be found.

Receiving one Document by _id

So what we need is a method that takes the id (_id) of a project as a parameter and returns then the corresponding ProjectTO-object. For that the mapping from the JSON-representation is required, but one step at a time. First the part that finds the document.

@Override
public ProjectTO read(String id) {
	DBCollection collection = handler.getCollection(COLLECTION_NAME_PROJECTS);
 
	BasicDBObject dbObject = new BasicDBObject();
	dbObject.put("_id", id);
 
	DBObject jsonDoc = collection.findOne(dbObject);
	ProjectDocument projectDocument = new ProjectDocument();		
	return projectDocument.buildProjectTO(jsonDoc);
}

@Override public ProjectTO read(String id) { DBCollection collection = handler.getCollection(COLLECTION_NAME_PROJECTS); BasicDBObject dbObject = new BasicDBObject(); dbObject.put("_id", id); DBObject jsonDoc = collection.findOne(dbObject); ProjectDocument projectDocument = new ProjectDocument(); return projectDocument.buildProjectTO(jsonDoc); }

As we know precisely that there can be only one project for a given id the findOne(…)-method is used here. In order to search for a specific project a corresponding “search-document” is created first and then passed as an argument to the find-method. That method returns the data in JSON-format, which then needs to be converted to our ProjectTO-representation. This is done in the ProjectDocument-class as follows.

/**
 * Building a ProjectTO from a given JSON document.
 * @param jsonDoc JSON Document
 * @return ProjectTO
 */
public ProjectTO buildProjectTO(DBObject jsonDoc) {
	ProjectTO projectTO = new ProjectTO();
	projectTO.setId((String) jsonDoc.get(DOCUMENT_ATTRIBUTE_ID));
	projectTO.setName((String) jsonDoc.get(DOCUMENT_ATTRIBUTE_NAME));
	projectTO.setDescription((String) jsonDoc.get(DOCUMENT_ATTRIBUTE_DESC));
 
	Map<String, Map<String, String>> environmentParameter = 
			(Map<String, Map<String, String>>) jsonDoc.get(DOCUMENT_ATTRIBUTE_RUNTIME_DEFINITIONS);
	projectTO.setEnvironmentParameter(environmentParameter);
 
	return projectTO;
}

/** * Building a ProjectTO from a given JSON document. * @param jsonDoc JSON Document * @return ProjectTO */ public ProjectTO buildProjectTO(DBObject jsonDoc) { ProjectTO projectTO = new ProjectTO(); projectTO.setId((String) jsonDoc.get(DOCUMENT_ATTRIBUTE_ID)); projectTO.setName((String) jsonDoc.get(DOCUMENT_ATTRIBUTE_NAME)); projectTO.setDescription((String) jsonDoc.get(DOCUMENT_ATTRIBUTE_DESC)); Map<String, Map<String, String>> environmentParameter = (Map<String, Map<String, String>>) jsonDoc.get(DOCUMENT_ATTRIBUTE_RUNTIME_DEFINITIONS); projectTO.setEnvironmentParameter(environmentParameter); return projectTO; }

What is really nice here is how easy it is to retrieve the Map of Maps for the environment parameters. This is thanks to the fact that the BasicDBObject-class is implementing the Map-interface as well. Of course this makes perfectly sense, as the JSON-format is a kind of big nested map. Nevertheless it is nice it works so easily. Again this can be tested using a kind of integration-test that is implemented using JUnit.

@Test
public void testProjectReadOneProject() {
 
	ProjectService rep = new MongoProjectRepository(handler);
	ProjectTO read = rep.read("rating_engine");		
	System.out.println("ID  : " + read.getId());
	System.out.println("Name: " + read.getName());
	System.out.println("Desc: " + read.getDescription());
 
	for (String envs : read.getEnvironmentParameter().keySet()) {
		System.out.println("Environment: " + envs);
		Map<String, String> paramsMap = read.getEnvironmentParameter().get(envs);
		for (String param : paramsMap.keySet()) {
			System.out.println("   " + param + " : " + paramsMap.get(param));
		}
	}
}

@Test public void testProjectReadOneProject() { ProjectService rep = new MongoProjectRepository(handler); ProjectTO read = rep.read("rating_engine"); System.out.println("ID : " + read.getId()); System.out.println("Name: " + read.getName()); System.out.println("Desc: " + read.getDescription()); for (String envs : read.getEnvironmentParameter().keySet()) { System.out.println("Environment: " + envs); Map<String, String> paramsMap = read.getEnvironmentParameter().get(envs); for (String param : paramsMap.keySet()) { System.out.println(" " + param + " : " + paramsMap.get(param)); } } }

To have something to look at the fetched project-document is printed to the console. This results in:

ID  : rating_engine
Name: Rating Engine
Desc: This is the test project for the rating engine calculating values ...
Environment: local
   selenium-server : localhost
   selenium-port : 8867
Environment: test
   selenium-server : test
   selenium-port : 8892

Looks fine when comparing it with the document we have created in the previous part of this series. Ok, now keeping a later GUI for this project in mind for sure we need a way to retrieve all available projects from the database. Surprisingly this is what the next paragraph is all about.

Receiving all Project-Documents

Before continuing with the next part of the code to load all project-documents it is time for another wrap-up. As mentioned already a few times before – and this has not changed – it is very easy to implement what is needed for these basic read/write-operations. I am still convinced that doing the same thing using a SQL-database would have taken me longer, but I might come to the point where I do the SQL-implementation, then I can be sure :-). Another point is that I am realising that the way I have structured the MongoDB-schema and thus the different documents has influenced me in the design of my business objects (so far only the ProjectTO). This must not necessarily be a bad thing, but it is notable.

But now back to reading in all the project-documents. Again this does not require a very complicated query as can be seen in the following.

@Override
public List<ProjectTO> read() {
 
	List<ProjectTO> list = new ArrayList<ProjectTO>();
 
	DBCollection collection = handler.getCollection(COLLECTION_NAME_PROJECTS);
	DBCursor cursor = collection.find();
 
	ProjectDocument projectDocument = new ProjectDocument();		
	while (cursor.hasNext()) {
		ProjectTO projectTO = projectDocument.buildProjectTO(cursor.next());
		list.add(projectTO);
	}
	cursor.close();
 
	return list;
}

@Override public List<ProjectTO> read() {List<ProjectTO> list = new ArrayList<ProjectTO>();DBCollection collection = handler.getCollection(COLLECTION_NAME_PROJECTS); DBCursor cursor = collection.find();ProjectDocument projectDocument = new ProjectDocument(); while (cursor.hasNext()) { ProjectTO projectTO = projectDocument.buildProjectTO(cursor.next()); list.add(projectTO); } cursor.close(); return list; }

Nothing to comment here I would say, as MongoDB allows for a very straightforward approach for reading in all the documents from one collection. All JSON-documents retrieved this way are then converted to ProjectTOs the same way one individual document has been converted. Another test-method is used for a first check of the implementation.

@Test
public void testProjectReadAllProjects() {
 
	ProjectService rep = new MongoProjectRepository(handler);
	List<ProjectTO> read = rep.read();		
 
	for (ProjectTO projectTO : read) {
		System.out.println(projectTO.getId() + " -> " + projectTO.getName());
	}	
}

@Test public void testProjectReadAllProjects() {ProjectService rep = new MongoProjectRepository(handler); List<ProjectTO> read = rep.read(); for (ProjectTO projectTO : read) { System.out.println(projectTO.getId() + " -> " + projectTO.getName()); } }

And again no surprises as exactly those two documents are printed out, which have been created beforehand with another testcase.

rating_engine -> Rating Engine
cloud_store -> Cloud Store

To get a complete overview on this it might be best to check out the complete project from GitHub. After being able to create new project-documents and reading them in again next time updating and removing those documents would be a natural topic. Stay tuned :-).


The MongoDB class series

Part 1 – MongoDB: First Contact
Part 2 – MongoDB: Second Round
Part 3 – MongoDB: Close Encounters of the Third Kind
Part 4 – MongoDB: I am Number Four
Part 5 – MongoDB: The Fith Element
Part 6 – MongoDB: The Sixth Sense
Part 7 – MongoDB: Tutorial Overview and Ref-Card

Java Supplemental Series

Part 1 – MongoDB: Supplemental – GRIDFS Example in Java
Part 2 – MongoDB: Supplemental – A complete Java Project – Part 1
Part 3 – MongoDB: Supplemental – A complete Java Project – Part 2