2. Background
• Mongo Stores documents in JSON format
• Jackson plays roles in serializing and de-
serializing java/scala objects
3. Options
• What are my options for serialization and
deserialization
– Manual
– Jackson
– Morphia
• Which one should I use?
4. Options Continued
• One solution doesn’t fit all
• Jackson provides following advantages
– Faster to development compared to Manual technique
– Unified annotations across all layers compared to Morphia
– Handles the types more friendlier way, example: Changing
data type from long to int is transparently handled by
jackson compared to manual technique
– We can also have different mappers between DB and
Jersey layers (Example: Date format in REST calls can be
different from date formats in mongo)
5. • Saving object using Jackson
TestObjectWithDate obj= new TestObjectWithDate(1, "String 1",1, new Date());
DBObject dbo = (DBObject)JSON.parse(mapper.writeValueAsString(obj));
coll.save(dbo);
• Saving object using manual mapping (this is top level object, if more levels in
object graph , this code can definitely much more lengthier)
TestObjectWithDate obj2 = new TestObjectWithDate(1, "String 1",1, new Date());
BasicDBObject dbo2 = new BasicDBObject();
dbo.put("_id", obj.getId());
dbo.put("stringVal", obj.getStringVal());
•
dbo.put("longVal", obj.getLongVal());
dbo.put("dateVal", obj.getDateVal());
coll.save(dbo2);
6. • Retrieve object using Jackson
DBObject queryObj = coll.findOne();
TestObjectWithDate afterSave = mapper.readValue(queryObj.toString(),TestObjectWithDate.class);
• Retrieve object using manual mapping
BasicDBObject dbObj = (BasicDBObject)coll.findOne();
TestObjectWithDate obj= new TestObjectWithDate();
obj.setId(dbObj.getLong("_id"));
obj.setStringVal(dbObj.getString("stringVal"));
obj.setLongVal(dbObj.getLong("longVal"));
obj.setDateVal((Date)dbo.get("dateVal"));
7. Challenges
• Mongo stores dates in bson format so we
need custom serializer and deserializer for
date data type
Regular Date output:
{dt: "2012-08-03T14:57:40.813Z"}
For mongo to store using date data type we need following format
{dt:{“$date “:"2012-08-03T14:57:40.813Z"}}
8. public class BsonDateSerializer extends StdSerializer<Date> {
public BsonDateSerializer() {
super(Date.class);
}
@Override
public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeStartObject();
serializeContents(value, jgen, provider);
jgen.writeEndObject();
}
private void serializeContents(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeFieldName("$date");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
jgen.writeString(dateFormat.format(value));
}
}
9. public class BsonDateDeserializer extends JsonDeserializer<Date> {
public BsonDateDeserializer() {
}
public Date deserialize(JsonParser jp, com.fasterxml.jackson.databind.DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode tree = jp.readValueAsTree();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
try{
return dateFormat.parse(tree.get("$date").textValue());
}catch(Throwable t){
throw new IOException(t.getMessage(), t);
}
}
}
How fast is Jackson compared to other options?
10. Benchmarks
• Mac OS X, 10.7.3, 2.4 GHz, i7, 8GB, 1333 MHz, DDR3 machine
250000 238095
200000
170357 173010
158227
150000
100000
50000 38183
26205 27624 28296
6461 3792 3925 4379
0
Manual Jackson Jackson 2 Morphia Manual Jackson Jackson 2 Morphia Manual Jackson Jackson 2 Morphia
Full Object One level Top level