MongoDB came with all sophisticated ObjectId generation feature, but often you just jumped the ship from relational database, and you still want an easy to read / communicate numeric identifier field which automatically increments every time new record is inserted.
One neat suggestion from MongoDB tutorial is to use a counter collection with a ‘counter name’ as its id, and a ‘seq’ field to store the last used number:
db.counters.insert({
_id: "users",
seq: 0
})
Then use findAndModify function to increment and obtain the next value.
db.counters.findAndModify({
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
})
When developing using Spring Data MongoDB, this neat trick can be written as a simple service. Here I used the collection name as the counter name so it’s easy to guess / remember.
import static org.springframework.data.mongodb.core.query.Query.*;
import static org.springframework.data.mongodb.core.query.Criteria.*;
import static org.springframework.data.mongodb.core.FindAndModifyOptions.*;
public class CounterService {
private MongoOperations mongo;
public int getNextSequence(String collectionName) {
Counter counter = mongo.findAndModify(
query(where("_id").is(collectionName)),
new Update().inc("seq", 1),
options().returnNew(true),
Counter.class);
return counter.getSeq();
}
}
Counter is just a simple class representing the collection. Please beware the usage of int data type, this will limit to 2^31 entries maximum.
(collection = "counters")
public class Counter {
@Id private String id;
private int seq;
/* getters & setters .. */
}
Then when inserting a new entry (with help of ), just set the id field like this before you save it
User newUser = new User();
newUser.setId(counterService.getNextSequence("users"));
newUser.setUsername(username);
newUser.setPassword(password);
userRepository.save(newUser);
You’ll get an incrementing simple numeric id each time you insert new object