MongoDB java client's WriteConcern doesn't

2019-09-13 17:16发布

I am a newbie to use MongoDB. I just imported the latest MongoDB java client via Maven:

    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>3.2.2</version>
    </dependency>

And then I wrote a very simple program to test the insert operation.

        //I use a replicaset
    MongoClient mongoClient = new MongoClient(
            Arrays.asList(new ServerAddress("10.12.16.136", 29017),
                    new ServerAddress("10.12.16.136", 29018),
                    new ServerAddress("10.12.16.136", 29019)));

    //I just want to write and ignore any database errors. (This does not work)
    mongoClient.setWriteConcern(WriteConcern.UNACKNOWLEDGED);

    //Get database and collection
    MongoDatabase database = mongoClient.getDatabase("test");
    MongoCollection<Document> collection = database.getCollection("realtime");

    //This does not work too.
    collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED);

    //Make a simple object to insert. I already have a document with the same _id in the database and I don't want to see the exception via the WriteConcern operation.
    Document doc = Document("longitude", longitude)
            .append("latitude", latitude)
            .append("velocity", velocity)
            .append("soc", soc)
            .append("_id", 12345678);

    //WriteConcern.UNACKNOWLEDGED doesn't work. An exception will be raised.
    collection.insertOne(doc);

How can I do the right thing?

2条回答
三岁会撩人
2楼-- · 2019-09-13 17:51

I had got this exception, when on empty collection was already present in MongoDB, and i was trying to create one more same collection by mistake, so when i deleted the existing collection and then did a post API, then it worked fine for me.. So better first drop your existing collection and then try to call any CRUD API.. if there is one Java entity with Collection ( name="STUDENT" ) , and you are again trying to create one collection with name student, this error comes

查看更多
何必那么认真
3楼-- · 2019-09-13 17:55

That's because collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED); generates a new MongoCollection object with a different write concern which you never use:

/** * Create a new MongoCollection instance with a different write concern. * * @param writeConcern the new {@link com.mongodb.WriteConcern} for the collection * @return a new MongoCollection instance with the different writeConcern */

MongoCollection withWriteConcern(WriteConcern writeConcern);

The following code:

MongoCollection<Document> dup = collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED);
...
dup.insertOne(doc);

should work, i.e. no error raised.

As for the MongoClient level write concern which is not propagated to the database:

public MongoDatabase getDatabase(final String databaseName) {
    MongoClientOptions clientOptions = getMongoClientOptions();
    return new MongoDatabaseImpl(databaseName, clientOptions.getCodecRegistry(), clientOptions.getReadPreference(),
            clientOptions.getWriteConcern(), createOperationExecutor());
}

As you can see, the write concern is taken from MongoClientOptions ignoring the parameter value passed to mongoClient.setWriteConcern() method, which may be a bug.

So, to set a global write concern properly, you will have to create an instance of MongoClientOptions:

 MongoClientOptions options = MongoClientOptions
     .builder()
     .writeConcern(WriteConcern.UNACKNOWLEDGED)
     .build();

and pass it to the MongoClient constructor.

查看更多
登录 后发表回答