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
Thanks Gerry…Exactly what I wanted…Worked perfect !!!