Skip to content

Commit

Permalink
fixed DAO write errors when collection contains documents with duplic…
Browse files Browse the repository at this point in the history
…ate _id, third try
  • Loading branch information
albogdano committed May 23, 2023
1 parent b8311d3 commit 23f6c9d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.mongodb.client.MongoCursor;
import com.mongodb.client.model.BulkWriteOptions;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.ReplaceOneModel;
import com.mongodb.client.model.ReplaceOptions;
import com.mongodb.client.model.UpdateOneModel;
import com.mongodb.client.model.WriteModel;
Expand Down Expand Up @@ -206,7 +207,7 @@ public <P extends ParaObject> void createAll(String appid, List<P> objects) {
}
try {
// fix duplicate _id errors by using a map
Map<String, Document> docs = new LinkedHashMap<>();
List<WriteModel<Document>> bulkOperations = new ArrayList<>();
for (ParaObject so : objects) {
if (so != null) {
if (StringUtils.isBlank(so.getId())) {
Expand All @@ -217,14 +218,14 @@ public <P extends ParaObject> void createAll(String appid, List<P> objects) {
so.setTimestamp(Utils.timestamp());
}
so.setAppid(appid);
if (docs.containsKey(so.getId())) {
logger.warn("Duplicate id found in batch which will be overwritten: {}", so.getId());
}
docs.put(so.getId(), toRow(so, null, false, true));
Document doc = toRow(so, null, false, true);
Object id = doc.get(ID);
doc.remove(ID); // fix MongoWriteConcernException error
bulkOperations.add(new ReplaceOneModel<>(Filters.eq(ID, id), doc, new ReplaceOptions().upsert(true)));
}
}
if (!docs.isEmpty()) {
getTable(appid).insertMany(new ArrayList<>(docs.values()));
if (!bulkOperations.isEmpty()) {
getTable(appid).bulkWrite(bulkOperations);
}
} catch (Exception e) {
logger.error(null, e);
Expand Down
41 changes: 29 additions & 12 deletions src/test/java/com/erudika/para/server/persistence/MongoDBDAOIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package com.erudika.para.server.persistence;

import com.erudika.para.core.Sysprop;
import com.erudika.para.core.utils.Utils;
import java.util.Collections;
import java.util.List;
import org.junit.AfterClass;
import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -133,33 +135,48 @@ public void testFieldNameSanitization() {
@Test
public void testInsertManyWithIdDuplication() {
MongoDBDAO d = ((MongoDBDAO) dao());
d.create(new Sysprop("id:three"));
Sysprop s1 = new Sysprop("id:one");
Sysprop s2 = new Sysprop("id:two");
s2.setName("name1");
Sysprop s3 = new Sysprop("id:two");
s3.setName("name2");
Sysprop s4 = new Sysprop("id:three");

d.createAll(List.of(s1, s2, s3, s4));
s4.setName("name4");
Sysprop s5 = new Sysprop(Utils.getNewId());
s5.setName("name5");
s5.addProperty("_id", "id:three");
s5.addProperty("id", "id:three");
s5.addProperty("props", Collections.singletonMap("_id", "id:three"));
Sysprop s6 = new Sysprop(Utils.getNewId());
s6.setName("name6");
s6.addProperty("_id", "id:three");
s6.addProperty("id", "id:three");
s6.addProperty("props", Collections.singletonMap("_id", "id:three"));

d.createAll(List.of(s1, s2, s3, s4, s5, s6));

assertNotNull(d.read(s1.getId()));
assertNotNull(d.read(s2.getId()));
assertNotNull(d.read(s3.getId()));
assertNotNull(d.read(s4.getId()));
assertNotNull(d.read(s5.getId()));

s1.setName("updated");
s2.setName("updated");
s3.setName("updated");
s4.setName("updated");
s1.setName("updated1");
s2.setName("updated2");
s3.setName("updated3");
s4.setName("updated4");
s5.setName("updated5");

d.updateAll(List.of(s1, s2, s3, s4));
d.updateAll(List.of(s1, s2, s3, s4, s5));

assertEquals("updated", d.read(s1.getId()).getName());
assertEquals("updated", d.read(s2.getId()).getName());
assertEquals("updated", d.read(s3.getId()).getName());
assertEquals("updated", d.read(s4.getId()).getName());
assertEquals("updated1", d.read(s1.getId()).getName());
assertEquals("updated3", d.read(s2.getId()).getName());
assertEquals("updated3", d.read(s3.getId()).getName());
assertEquals("updated4", d.read(s4.getId()).getName());
assertEquals("updated5", d.read(s5.getId()).getName());

d.deleteAll(List.of(s1, s2, s3, s4));
d.deleteAll(List.of(s1, s2, s3, s4, s5, s6));
}

}

0 comments on commit 23f6c9d

Please sign in to comment.