1

I want to serialize ObjectId of my Product class to JSON. I got the following JSON:

[{"name":"Play for Java: Covers Play 2","type":"Book","company":"Manning Publications","price":30.0,"imagePath":"public/images/play-for-java.png","rating":4.5,"category":"Computer","author":"Nicolas Leroux","publicationDate":1396224000000,"numPage":320,"_id":539da7a6370882f10d5c2777}]

You can notice that the "_id" didn't be properly serialized, it should be "539da7a6370882f10d5c2777" (with double quotes) and not just 539da7a6370882f10d5c2777.

Therefore, I have tried to implement my own ObjectIdSerializer as following:

import java.io.IOException;

import org.bson.types.ObjectId;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class ObjectIdSerializer extends JsonSerializer<ObjectId> {
    @Override
    public void serialize(ObjectId value, JsonGenerator jsonGen,SerializerProvider provider) throws IOException,
            JsonProcessingException {
        jsonGen.writeString(value.toString());
    }
}

It gave me the different error: java.lang.String cannot be cast to org.bson.types.ObjectId (through reference chain: models.Book["_id"])

Here are my Product class and Book class:

Product.java

@JsonTypeInfo(use= JsonTypeInfo.Id.CLASS,property="_class")
public class Product {
    @ObjectId @Id
    @JsonSerialize(using = ObjectIdSerializer.class)
    protected String id;
    @JsonProperty("name")
    protected String name;
    @JsonProperty("type")
    protected String type;
    @JsonProperty("description")
    protected String description;
    @JsonProperty("company")
    protected String company;
    @JsonProperty("price")
    protected float price;
    @JsonProperty("imagePath")
    protected String imagePath;
    @JsonProperty("imageName")
    protected String imageName;
    @JsonProperty("rating")
    protected float rating;

    public Product() {
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    // Getters and setters
   ...    

Book.java

public class Book extends Product{

    @JsonProperty("category")
    private String category;
    @JsonProperty("author")
    private String author;
    @JsonProperty("publicationDate")
    private Date publicationDate;
    @JsonProperty("numPage")
    private int numPage;

    public Book() {
    }
    // Getters and setters   
   ...

Can you help me figure it out how can I properly serialize the ObjectId to JSON?

lvarayut
  • 13,963
  • 17
  • 63
  • 87

1 Answers1

4

It looks like Jackson has been customized to serialize the string id field in a special way. That is probably a part of the integration with org.bson library.

The problem is that your deserializer is parametrized by the ObjectId type instead of String or plain Object. Try to change it as follows and also remove the @ObjectId annotation from the field declaration. Here is an example:

public class ObjectIdSerializer extends JsonSerializer<Object> {
    @Override
    public void serialize(Object value, JsonGenerator jsonGen,SerializerProvider provider) throws IOException {
        jsonGen.writeString(value.toString());
    }
}

You may also consider adopting the Jackson-Jongo provider class to fix the object id serialization for all the classes.

Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
  • Thanks for you response. It's almost perfect except the serialized _id is a little bit strange, "_id":"\"539df7793708be9becea990e\"". Moreover, the `_id` in my MongoDB has changed from `"_id" : ObjectId("539e06e03708a8e88421cf6d")` to `"_id":"539e06e03708a8e88421cf6d"`. Is there a way to solve it? – lvarayut Jun 15 '14 at 21:01
  • Can you try to remove the ObjectId annotation? I have updated my answer with regards to it. – Alexey Gavrilov Jun 15 '14 at 21:22
  • It worked like a charm! Could you explain a bit why it does work by removing the `ObjectId`? Without the `ObjectId`, Is there any effect to my class in the future ? – lvarayut Jun 15 '14 at 22:02
  • I wonder what would happen if you just remove the ObjectId annotation and the JsonDeserialize? – Alexey Gavrilov Jun 16 '14 at 07:47
  • I got `"_id" : "539e9c70ccf270420d3e96a8"`, however, I don't know if it is good to keep the `_id` as string instead of `ObjectId`. – lvarayut Jun 16 '14 at 08:32
  • I am new to Spring. Where should I add this class? Does it require @Configuration annotation? Thanks. – zookastos Apr 29 '20 at 19:31