MongoJsonMappingException: Error mapping BSON to POJOs

1,532 views
Skip to first unread message

Simone Hinterseher

unread,
May 22, 2012, 10:23:16 PM5/22/12
to mongo-jackson-mapper
I would like to provide an ObjectId myself when inserting documents
into mongodb.
I think I basically copied part of the code from the tutorial:
http://vznet.github.com/mongo-jackson-mapper/object-ids.html

I'm actually not a 100% sure about the usage difference of @ObjectId
and @Id/@JsonProperty("_id"), but i played with several variations and
they all turn out the same..

This is basically my setup:

public class MyClass {

private String someId;

@ObjectId @Id
public String getSomeId() {
return someId;
}
@ObjectId @Id
public void setSomeId(String someId) {
this.someId = someId;
}
}


public class MongoTest {
public static void main(String[] args) throws UnknownHostException,
MongoException {
Mongo mongo = new Mongo("localhost", 27017);
DB db = mongo.getDB("myDB");

JacksonDBCollection<MyClass, String> myClassCollection =
JacksonDBCollection.wrap(db.getCollection("myclass"),
MyClass.class, String.class);

MyClass myClass = new MyClass();
myClass.setSomeId("myId");

myClassCollection.insert(myClass);
}
}



Exception in thread "main"
net.vz.mongodb.jackson.MongoJsonMappingException: Error mapping BSON
to POJOs
at
net.vz.mongodb.jackson.JacksonDBCollection.convertToDbObject(JacksonDBCollection.java:
1545)
at
net.vz.mongodb.jackson.JacksonDBCollection.insert(JacksonDBCollection.java:
236)
at com.example.MongoTest.main(MongoTest.java:27)
Caused by: org.codehaus.jackson.map.JsonMappingException: invalid
ObjectId [myId] (through reference chain: com.example.MyClass["_id"])
at
org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:
218)
at
org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:
183)
at
org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:
140)
at
org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:
158)
at
org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:
112)
at
org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:
610)
at
org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:
256)
at org.codehaus.jackson.map.ObjectMapper.writeValue(ObjectMapper.java:
1613)
at
net.vz.mongodb.jackson.JacksonDBCollection.convertToDbObject(JacksonDBCollection.java:
1543)
... 2 more
Caused by: java.lang.IllegalArgumentException: invalid ObjectId [myId]
at org.bson.types.ObjectId.<init>(ObjectId.java:128)
at org.bson.types.ObjectId.<init>(ObjectId.java:122)
at
net.vz.mongodb.jackson.internal.ObjectIdSerializer.serialiseObject(ObjectIdSerializer.java:
52)
at
net.vz.mongodb.jackson.internal.ObjectIdSerializer.serialize(ObjectIdSerializer.java:
44)
at
org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:
446)
at
org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:
150)
... 7 more

Any help is greatly appreciated!

James Roper

unread,
May 30, 2012, 5:19:05 AM5/30/12
to mongo-jack...@googlegroups.com
@Id is shorthand for @JsonProperty("_id").  If you set @JsonProperty("_id"), you don't need @Id.

ObjectId is a *datatype*.  It is a 12 byte value, which, when expressed as a String, is a 24 digit hexadecimal number.  It is similar to using a Long, except that a long is 8 bytes (64 bits), an ObjectId however is 96 bits, and these extra bits allow MongoDB to generate IDs that can be guaranteed to be unique with a high level of certainty.

The @ObjectId annotation is used for when you want to use ObjectIds in MongoDB, but you want to work with these IDs as ordinary strings in your code.  On the other hand, if you wanted to work with ObjectIds in MongoDB, but also wanted these to be represented as ObjectIds in the code, you would declare your properties of type org.bson.types.ObjectId, and not use the @ObjectId annotation.

If you want to use your own IDs, ie if you *don't* want to use ObjectIds, then simple don't use the @ObjectId annotation.  MongoDB will then store it as the type you declared (eg, String, Long, Date, whatever).  

So, in your example above, if you wanted to use "myid" as an id, your class should look like this:

public class MyClass { 

    private String someId; 

    @Id 
    public String getSomeId() { 
        return someId; 
    } 
    @Id 
    public void setSomeId(String someId) { 
        this.someId = someId; 
    } 
}

The only thing to make sure here is that you *always* set a value for someId.  If you don't MongoDB will generate an ObjectId for you.  This will end up being an ObjectId in the database, and will be deserialised as a String, but when you go to query by that ID, it won't work, because it will look for properties that are of type String, whereas in the database its stored as an ObjectId, and so won't match.

Cheers,

James

Arif hosain

unread,
Mar 23, 2015, 6:51:58 AM3/23/15
to mongo-jack...@googlegroups.com
To recover from this error you need to write a statement.
@Id
@ObjectId;
public String id;

done.........
Reply all
Reply to author
Forward
0 new messages