Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring data Mongodb bulk save continue on error

I'm using spring-data-mongodb and have a simple repository which is configured with the following configuration:

@Configuration
@EnableMongoRepositories(basePackages = "com.my.package")
@Profile("default")
public class MongoConfig extends AbstractMongoConfiguration {

    @Value("${mongo.db.uri}")
    private String mongoDbUri;
    @Value("${mongo.db.database}")
    private String mongoDbDatabaseName;

    @Override
    protected String getDatabaseName() {
        return mongoDbDatabaseName;
    }

    @Override
    public MongoClient mongoClient() {
        return new MongoClient(new MongoClientURI(mongoDbUri));
    }
}

The used repository extends the CrudRepository, which makes that I can call the saveAll() method. By default, doing a saveAll (bulk operation) in mongodb will stop when one record fails, unless an option was passed to the insertMany/updateMany command to have "continueOnError" to true or have "BulkMode.unordered". Is there any way I can configure spring data to always continue on error (or always do an unordered insert/update), so that doing a saveAll will always try the whole bulk, even if some records fail?

Thanks!

like image 852
user45 Avatar asked Sep 01 '25 05:09

user45


1 Answers

To engage a MongoDB bulk write (with the ability to choose an unordered op which in turn allows the write to continue even after one of the items in the bulk group fails) you need to use org.springframework.data.mongodb.core.BulkOperations (available from Spring Data >= 1.9.0.RELEASE)

For example:

BulkOperations bulkOperations = mongoTemplate.bulkOps(BulkMode.UNORDERED, YourDomainObjectClass.class);
for (YourDomainObject ydo : yourDomainObjects) {
    bulkOperations.insert(ydo);
}
BulkWriteResult result = bulkOperations.execute();
// inspect the result
if (result.getInsertCount() != yourDomainObjects.size()) {
    // oh oh
}

If you are using Spring Data version < 1.9.0.RELEASE then you could use the native driver object: DBCollection (available via MongoOperations.getCollection()) and the go with standard driver calls such as:

BulkWriteOperation bulkWriteOperation = collection.initializeUnorderedBulkOperation();
for (YourDomainObject ydo : yourDomainObjects) {
    bulkWriteOperation.insert(ydo);    
}
BulkWriteResult result = bulkWriteOperation.execute();
// inspect the result
if (result.getInsertCount() != yourDomainObjects.size()) {
    // oh oh
}
like image 184
glytching Avatar answered Sep 03 '25 01:09

glytching