MongoDB è dotato di tutte le sofisticate funzionalità di generazione di ObjectId, ma spesso sei semplicemente saltato dalla nave dal database relazionale e desideri comunque un campo identificatore numerico di facile lettura/comunicazione che si incrementi automaticamente ogni volta che viene inserito un nuovo record.
Un ottimo suggerimento del tutorial di MongoDB è quello di utilizzare una raccolta di contatori con un "nome contatore" come ID e un campo "seq" per memorizzare l'ultimo numero utilizzato.
Quando si sviluppa utilizzando Spring Data MongoDB, questo trucco accurato può essere scritto come un semplice servizio. Qui ho usato il nome della raccolta come nome del contatore, quindi è facile da indovinare / ricordare.
import static org.springframework.data.mongodb.core.FindAndModifyOptions.options;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import com.model.CustomSequences;
@Service
public class NextSequenceService {
@Autowired private MongoOperations mongo;
public int getNextSequence(String seqName)
{
CustomSequences counter = mongo.findAndModify(
query(where("_id").is(seqName)),
new Update().inc("seq",1),
options().returnNew(true).upsert(true),
CustomSequences.class);
return counter.getSeq();
}
}
CustomSequences è solo una semplice classe che rappresenta la raccolta. Fai attenzione all'utilizzo del tipo di dati int, questo limiterà a un massimo di 2^31 voci.
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "customSequences")
public class CustomSequences {
@Id
private String id;
private int seq;
// getters and setters
}
Quindi, quando inserisci una nuova voce (con l'aiuto del supporto Spring MongoDB Repository), imposta il campo id in questo modo prima di salvarlo
BaseQuestion baseQuestion = new BaseQuestion();
baseQuestion.setQuestionId(nextSequenceService.getNextSequence("customSequences"));
/* Rest all values */
baseQuestionRepository.save(baseQuestion);
Se non ti piace in questo modo, devi utilizzare MongoDBEvents e utilizzare onBeforeConvert per generare valore automatizzato utilizzando lo stesso approccio di cui sopra.
Anche l'approccio precedente è threadsafe poiché findAndModify() è un metodo atomico thread-safe