I've just started working on a project using the play framework,jongo and MongoDB. The project was initially written in Play 2.1 with pojos with an String id field annotated with both: @Id and @ObjectId This would persist to Mongo as an ObjectId and when deserialized would output the id as: "id":"53fcb9ede4b0b18314098d10" for example.
Since upgrading to Jongo 1.1 and Play 2.3.3 the id attribute is always named "_id" when deserialized, I want the attribute to retain the field name yet I can't use @JsonProperty("custom_name") as the Jongo @Id annotation does @JsonProperty("_id") behind the scenes.
import org.jongo.marshall.jackson.oid.Id;
import org.jongo.marshall.jackson.oid.ObjectId;
public class PretendPojo {
@Id
@ObjectId
private String id;
private String name;
public PretendPojo() {
}
public PretendPojo(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
The POJOs when persisted in MongoDB look like this if I view them via RoboMongo
{
"_id" : ObjectId("53fc984de4b0c34f1905b8ee"),
"name" : "Owen"
}
However when I deserialize them I get the following json if I keep both annotations:
{"name":"Owen","_id":{"time":1409072858000,"date":1409072858000,"timestamp":1409072858,"new":false,"timeSecond":1409072858,"inc":308487737,"machine":-458223042}}
and the following output if I only use the @Id annotation.
{"name":"Owen","_id":"53fcbedae4b0123e12632639"}
I have a test case for working with the PretendPojo show above:
@Test
public void testJongoIdDeserialization() throws UnknownHostException {
DB database = new MongoClient("localhost", 27017).getDB("jongo");
Jongo jongo = new Jongo(database);
MongoCollection collection = jongo.getCollection("jongo");
collection.save(new PretendPojo("Owen"));
PretendPojo pretendPojo = collection.findOne("{name: \"Owen\"}").as(PretendPojo.class);
JsonNode json = Json.toJson(pretendPojo);
assertNotNull(json.get("id"));
}
When trying to use custom deserializers I never can get hold of the object ID I seem to only have access to the date/time/timestamp data that is currently being deserialized.
Ideally the output I'm looking for would be:
{"name":"Owen","id":"53fcbedae4b0123e12632639"}
Any help will be greatly appreciated! :)
You can try using @JsonValue, Jongo does not seem to use them, but without any response from the developers this behaviour might be subject to change in future releases.
The more proper solution would be to try combining
@JsonView
with@Id
annotationRemember to specify which View to use on Jongo's ObjectMapper and your Jackson ObjectMapper (the one to use in REST layer, I presume)
ObjectIdSerializer always writes property mapped with @ObjectId to a new instance of ObjectId. This is wrong when you map this property to a String.
To avoid this behaviour, I've write a NoObjectIdSerializer :
used like this :
There is an open issue.
I think that there is an annotation in jackson that allows you to change the property name, I think is : @JsonProperty but you can see all the possible annotations in this link:
https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations
I hope this solve your problem
The Jongo's behaviour has changed since 1.1 for a more consistent handling of its owns annotations.
If your '_id' is a String and you want this field to be stored into Mongo as a String then only @Id is needed.
@Id + @ObjectId on a String property means :
"My String property named 'foo' is a valid ObjectId. This property has to be stored with the name '_id' and have to be handled as an ObjectId."