【发布时间】:2020-02-16 03:17:27
【问题描述】:
我正在尝试为 _id 分配唯一的 int。我知道 ObjectID 是一个不错的选择,但在我的情况下我需要使用 int 作为 ID。我正在使用 Random 生成随机 int 来为其分配新对象。
这是错误:
Exception in thread "main" com.mongodb.MongoWriteException: E11000 duplicate key error
collection: TOP100SongsUK.artists index: _id_ dup key: { _id: 484624875 }
但事实并非如此。目前,我的收藏有一些记录,这是不可能的。什么可能是触发此问题的原因?
这是写入数据库的方法,最后一个方法分配一个 ID。
public boolean add(Artist artist) {
Document artistToInsert = new Document();
artistToInsert.append(ARTIST_ID, assignArtistID()).append(ARTIST_NAME, artist.getName());
boolean validOperation = false;
int attempts = 0;
do {
try {
addArtist(artistToInsert);
validOperation = true;
} catch (DuplicateKeyException e) {
attempts++;
System.out.println("Incorrect ID for Artist");
}
} while (!validOperation || attempts < 3);
if (attempts == 3) {
throw new RuntimeException("Unable to add Artist - Mongo");
}
return true;
}
private boolean addArtist(Document artistToInsert) {
artistCollection.insertOne(artistToInsert);
return true;
}
private static Random intGenerator = new Random();
private int assignArtistID() {
return Math.abs(intGenerator.nextInt());
}
更新:getNextSequence 函数:
static final String ID_PARAM = "idParam";
static final String ID_SEQ = "seq";
static int getNextSequence(MongoCollection<Document> collection){
Document findRequest = new Document();
findRequest.append("_id", ID_PARAM);
Document updateRequest = new Document();
updateRequest.append("$inc", new Document(ID_SEQ,1));
FindOneAndUpdateOptions options = new FindOneAndUpdateOptions();
options.upsert(true);
options.returnDocument(ReturnDocument.AFTER);
Document returnDoc = collection.findOneAndUpdate(findRequest,updateRequest,options);
return (int) returnDoc.get(ID_SEQ);
}
【问题讨论】:
-
在Generating Globally Unique Identifiers for Use with MongoDB 上查看这篇文章。具体来说,子主题“确保数据库级别的标识符唯一性”。