Fork me on GitHub

Using Object IDs

The simplest way to use ObjectId elements, both for document IDs and also for references to other documents (or anything) is to declare the field to have a type of org.bson.types.ObjectId. MongoJack will handle serialisation/deserialisation of these with no problems. If you name the ID field “_id”, no extra configuration is required. If you want to name the primary ID field something else, you will need to annotate it with javax.persistence.Id.

However, there are some use cases where you may not want to use the ObjectId type, for example, if the same objects get serialised to the web, or if you just prefer dealing with more basic types. MongoJack provides some support for this, though there are a few areas that you need to be careful about.

Other Types

If you declare your “_id” field (or a field annotated with @javax.persistence.Id) to have any supported type (e.g. String, or Long), and generate or fill out the field value yourself, MongoJack will generally save and retrieve the values adequately; it wont’ use the built-in org.bson.types.ObjectId, but a Long or String id generated in some other way in the Java code should be perfectly valid.

If you declare your “_id” of type String, Mongo’s insert methods will generate an object-id value for the field, but it will be saved as a String, not an ObjectId, which probably isn’t what you want.

@ObjectId

The @org.mongojack.ObjectId annotation can be added to any String or byte[] field to indicate that you want its value to be stored as an ObjectId. It can also be added to org.mongojack.DBRef fields who’s ID type paramater is String or byte[], as well as collection/array fields and Map fields. This annotation instructs MongoJack to serialise the given value into an ObjectId, and deserialise any encountered ObjectIds into the type of the field. The following are all valid uses:

public class MyClass {
    @ObjectId
    public String _id;
    @ObjectId
    public byte[] someArbitraryId;
    @ObjectId
    public List<String> arbitraryCollectionOfIds;
    @ObjectId
    public DBRef<AnotherClass, byte[]> anotherObject;
    @ObjectId
    public List<DBRef<AnnotherClass, String> collectionOfOtherObjects;
    @ObjectId
    public Map<String, String> mapOfStringsToObjectIds;
}

What is not currently supported is multi dimensional arrays/collections. Serialising map keys to ObjectIds are naturally not supported because MongoDB does not support ObjectIds as key values.

If using getters and setters, the annotation must be added to both the getter and the setter, for example:

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

If using property based @JsonCreator methods, then it must be added to the parameter:

public class MyClass {
    private final String someId;
    @JsonCreator
    public MyClass(@ObjectId @JsonProperty("someId") someId) {
        this.someId = someId;
    }
    @ObjectId
    public String getSomeId() {
        return someId;
    }
}

If using custom (de)serialisers or delegate @JsonCreator methods, then you will need to handle the ObjectIds yourself.

If the setter for the _id field of the object is annotated with @ObjectId, then the *ById() methods on JacksonMongoCollection will use serialise the passed in parameter to an ObjectId for you, and WriteResult.getSavedId() will deserialise it from ObjectId. If using a custom deserialiser for the bean, this will not work, even if the getter for the property is annotated with @ObjectId. This may be fixed in future, and is dependent on support from Jackson to give better information about configured serialisers.