BACKGROUND
Initially, Morphia was being used to interact with a mongo database. This was fine and worked nicely, but there was one caveat... Some mapping exception was being spilled and clogging the logs. See my Unresolved Question on that particular issue. <=== This didn't stop the application from functioning correctly. Morphia helped in getting the documents mapped to their corresponding entities (basically POJOs) and these were easily rendered to the Views.
However, after much deliberation and because that exception issue wasnt resolved, and thanks to the MongoDB Java Driver 3.0's new features, I have decided to move off from Morphia to MongoDB-Java-Driver3.0(MJD3.0)
On inspecting Documents (previously stored by morphia) I can see:
"_id" : ObjectId("55706df5e4b00146ea69622b"),
"className" : "packageName.NewsCategory",
"categoryName" : "Maritime",
"uid" : NumberLong(11),
"createdAt" : ISODate("2015-06-04T15:25:41.096Z"),
"updatedAt" : ISODate("2015-06-04T15:25:41.096Z"),
"active" : true
Also, the model, NewsCategory
, looks something like this;
public class NewsCategory{
private ObjectId id;
private String categoryName;
private Long uid;
private Date createdAt;
private Date updatedAt;
private boolean active;
//getters...
//setters...
}
MY STRATEGY
Because I was formerly using Morphia, the Models (as POJOs) were being passed as attributes to the Views ( .vm - velocity templates ) where values are being read from the fields as: $!newsCategory.id
, $!newsCategory.categoryName
, $!newsCategory.createdAt
e.g
<a href="/news/categories/$!newsCategory.id"> Edit </a>
Now, because I do not want to modify the Servelet and/or View Layer, I ensure that in the business Layer, the json
string gets deserialized into the corresponding Model using gson
;
NewsCategory newsCategory = new GsonBuilder().create().fromJson(json, NewsCategory.class);
CHALLENGE - 1
With document
Type being org.bson.Document
and using MongoDB-Java-Driver3.0 (MJD3.0), The NewsCategory
document is correctly retrieved from MongoDB, no problem, and when I call
String json = document.toJson();
...here's what the json structure looks like;
{
"_id": {
"$oid": "54ad4568e451500a45f60200"
},
"className": "packageName.NewsCategory",
"categoryName": "General",
"uid": {
"$numberLong": "1"
},
"createdAt": {
"$date": 1420641640457
},
"updatedAt": {
"$date": 1429285029337
},
"active": true
}
THE PROBLEM
This json
structure derived from document.toJson()
cannot be easily deserialized to the corresponding NewsCategory
model using my earlier described strategy, thanks to those field types present in the format.
CHALLENGE - 2
I directly converted the document
to json using gson
as follows;
String json = new GsonBuilder().create().toJson(document);
...and here's what the json structure looks like;
{
"_id": {
"timestamp": 1420641640,
"machineIdentifier": 14963024,
"processIdentifier": 2629,
"counter": 16122368
},
"className": "packageName.NewsCategory",
"categoryName": "General",
"uid": 1,
"createdAt": "Jan 7, 2015 3:40:40 PM",
"updatedAt": "Apr 17, 2015 4:37:09 PM",
"active": true
}
This is way more desirable, and I can get the NewsCategory
object using my usual strategy as;
NewsCategory newsCategory = new GsonBuilder().create().fromJson(json, NewsCategory.class);
ANOTHER PROBLEM THOUGH
The _id
field has been broken into it's ObjectId
components, hence the id cannot be retrieved as newsCategory.id
or even newsCategory._id
.
However while I was formerly using morphia, it could simply be retrieved by just using newsCategory.id
MAIN QUESTIONS
What is the appropriate way to deserialize these json strings into the corresponding NewsCategory
Model while still ensuring that all the necessary fields are still normally accessible in the Views using the regular dot(.) annotations (especially that id
field)?
An approach for both CHALLENGES 1 & 2 described above would be highly appreciated.
Thanks!
EDIT:
I've tried @cichystefan's approach and the challenge still remains how to access the value of the _id
field
With newsCategory
now being of type org.bson.Document
, for quite obvious reasons, $!newsCategory.id
is apparently either empty or null, because when I inspect an html section in the view defined as <a href="/news/categories/$!newsCategory.id">
in google chrome here's what I see... <a href="/news/categories/">
...
Now, instinct says to fetch the _id
part by doing $!newsCategory._id
but this just spills the whole document as a string and appends the ._id
part at the end of the string.
<a href="/news/categories/Document{{_id=54ad4568e451500a45f60200, className=packageName.NewsCategory, categoryName=General, uid=1, version=2, createdAt=Wed Jan 07 15:40:40 WAT 2015, updatedAt=Fri Apr 17 16:37:09 WAT 2015, active=true}}._id">