Map field initialized with null, cannot be updated via mutateIn-upsert operation

java

#1

I have a java bean field map<key, object> which was initialized with null, but now I can no longer update with jsonObject via mutateIn-upsert operation.

I get the below exception.
Multiple mutation could not be applied. First problematic failure at 0 with status SUBDOC_PATH_MISMATCH; Multiple mutation could not be applied. First problematic failure at 0 with status SUBDOC_PATH_MISMATCH~ Path mapfield.key ends in a scalar value in documentId expected dictionary.

Is it possible to get rid of this when the field value is null?

Bucket.mutateIn(docId).upsert(mapfield.key, jsonObject, new SubdocOptionsBuilder().createPath(true))

SampleBean {
Map<key, Object> mapField;
}

Obviously mutateIn-upsert works just fine when the field isn’t there by default
using SDK 2.5.6, (same error with 2.5.9)


#2

Hi @mail.dipac. How do you want to final JSON to look afterwards? Are you trying to get rid of that field completely, set it to an empty object, or do you want to explicitly set it to the JSON null value?


#3

@graham.pople ah no. the field was set to NULL before, now trying add a subDocument JSON.

When the document is first inserted it added the “mapField” with NULL value as there was no data (ideally we should have used INCLUDE.NON_NULL so NULL java bean fields aren’t written to Couchbase, but we didn’t)
Initial State:
SampleBean {
field1: “fieldValue1”,
mapField: null
}

During an update the app now needs to add the mapField<String, Object> like
Did this:
Bucket.mutateIn(docId).upsert(mapfield.key1, jsonObject, new SubdocOptionsBuilder().createPath(true))
where jsonObject -> {
somekey1 : “somevalue1”,
somekey2: “somevalue2”
}

What I want it to look like:

SampleBean {
field1: “fieldValue1”,
mapField: {
“key1” : {
somekey1 : “somevalue1”,
somekey2: “somevalue2”
}
}

When i try to update using mutateIn.upsert, it fails with the listed error in the ticket above.


#4

@mail.dipac thanks for the additional info. Based on that I created this code:

        JsonObject obj = JsonObject.create()
                .put("field1", "fieldValue1")
                .putNull("mapField");

        bucket.insert(JsonDocument.create("test", obj));

        JsonObject toUpsert = JsonObject.create()
                .put("somekey1", "somevalue1")
                .put("somekey2", "somevalue2");

        bucket.mutateIn("test")
                .upsert("mapField", toUpsert, SubdocOptionsBuilder.builder().createPath(true))
                .execute();

which runs successfully on Couchbase Java SDK 2.5.6 and above (but fails with an INVALID_ARGUMENTS exception on SDK 2.5.5). So I can’t replicate your issue just yet, it seems to run ok for me. Perhaps you can compare this code against your own and narrow this down further?


#5

thanks @graham.pople , this would work when i know the key-value pairs for all the combinations under mapField.

When all I want to do is update a specific key under mapField like below, it would fail

        bucket.mutateIn("test")
            .upsert("mapField.somekey1", toUpsert, SubdocOptionsBuilder.builder().createPath(true))
            .execute();

#6

@mail.dipac ah I see. I was able to recreate your original problem with that modification. I ran some further tests and found that explicitly creating the paths like this works:

bucket.mutateIn("test")
        .upsert("mapField", JsonObject.create())
        .upsert("mapField.someField", toUpsert)
        .execute();