# Update by query don't accept user-defined param in java high level client

**URL:** <https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927>\
**Category:** Elasticsearch\
**Created:** [April 7, 2020, 3:09pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927 "2020-04-07T15:09:55Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![tnarita](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tnarita/32/62180_2.png) [@tnarita](https://discuss.elastic.co/u/tnarita)\
**Post date:** [April 7, 2020, 3:09pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/1 "2020-04-07T15:09:56Z")

</div>

Hi,

I'm using REST High Level Client in v7.5  
I'm getting error when I tried to update all document by UpdateByQueryRequest.  
Error message : **cannot write xcontent for unknown value of type class entity.Navigation**

Belows are my sample code.

```
private static void updateByQueryForNavigation() throws IOException {
    Navigation navi1 = new Navigation(Arrays.asList("1", "2", "3"), "2020-01-01T10:00:00", "2020-01-01T10:00:00");
    Navigation navi2 = new Navigation(Arrays.asList("4", "5", "6"), "2020-01-01T10:00:00", "2020-01-01T10:00:00");
    List<Navigation> naviList = new ArrayList<>();
    naviList.add(navi1);
    naviList.add(navi2);

    Map<String, Object> params = new HashMap<>();
    params.put("navigation", naviList);

    String source = "ctx._source.navigation = params.navigation";
    UpdateByQueryRequest request = new UpdateByQueryRequest("test");
    request.setScript(new Script(ScriptType.INLINE, "painless", source, params));

    client.updateByQuery(request, RequestOptions.DEFAULT);
}

```

=========================================================================

```
package entity;

import java.io.Serializable;
import java.util.List;

public class Navigation implements Serializable {
    private static final long serialVersionUID = 1L;

    private List<String> navigationCode;
    private String startDate;
    private String endDate;

    public Navigation(List<String> navigationCode, String startDate, String endDate) {
        this.navigationCode = navigationCode;
        this.startDate = startDate;
        this.endDate = endDate;
    }

    public Navigation() {
    }

    public List<String> getNavigationCode() {
        return navigationCode;
    }

    public String getStartDate() {
        return startDate;
    }

    public String getEndDate() {
        return endDate;
    }

}

```

If I convert naviList to json then set it into param, error doesn't happen but result is not what I expected. Json string is directly insert into document. My expectation is naviList is inserted as nested array object.  
Before

```
"hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "test name"
        }
      }
    ]

```

After(expectation)

```
"hits" : [
  {
    "_index" : "test",
    "_type" : "_doc",
    "_id" : "1",
    "_score" : 1.0,
    "_source" : {
      "navigation" : [
        {
          "endDate" : "2020-01-01T10:00:00",
          "navigationCode" : [
            "1",
            "2",
            "3"
          ],
          "startDate" : "2020-01-01T10:00:00"
        },
        {
          "endDate" : "2020-01-01T10:00:00",
          "navigationCode" : [
            "4",
            "5",
            "6"
          ],
          "startDate" : "2020-01-01T10:00:00"
        }
      ],
      "name" : "test name"
    }
  }
]

```

Below request works as expected. I just would like to achieve same output by Java High Level client.

```
POST /test/_update_by_query
{
  "script" : {
    "source" : "ctx._source.navigation = params.navigation",
    "params" : {
      "navigation" : [{"navigationCode":["1","2","3"],"startDate":"2020-01-01T10:00:00","endDate":"2020-01-01T10:00:00"},{"navigationCode":["4","5","6"],"startDate":"2020-01-01T10:00:00","endDate":"2020-01-01T10:00:00"}]
    },
    "lang" : "painless"
  }

```

}

I already checked below discussion but couldn't find answer.

> <https://stackoverflow.com/questions/54172523/elasticsearch-java-highlevel-client-update-script-with-params>

Thank you in advance.  
Tsubasa

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [April 7, 2020, 3:25pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/2 "2020-04-07T15:25:15Z")

</div>

You can not directly send a JavaBean to Elasticsearch. You need first to serialize it to json.  
You can use Jackson for that.

An example here:

> <https://github.com/dadoonet/legacy-search/blob/01-direct/src/main/java/fr/pilato/demo/legacysearch/dao/ElasticsearchDao.java#L67-L70>

---

<div class="post-metadata">

**Author:** ![tnarita](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tnarita/32/62180_2.png) [@tnarita](https://discuss.elastic.co/u/tnarita)\
**Post date:** [April 7, 2020, 3:40pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/3 "2020-04-07T15:40:30Z")

</div>

Hi,  
Thank you for your quick reply.

I changed my code like below but result wasn't what I expected. byte chars are directly inserted.  
How can I config updateByQueryRequest so that it can handle byte array data?

```
private static void updateByQueryForNavigation() throws IOException {
        Navigation navi1 = new Navigation(Arrays.asList("1", "2", "3"), "2020-01-01T10:00:00", "2020-01-01T10:00:00");
        Navigation navi2 = new Navigation(Arrays.asList("4", "5", "6"), "2020-01-01T10:00:00", "2020-01-01T10:00:00");
        List<Navigation> naviList = new ArrayList<>();
        naviList.add(navi1);
        naviList.add(navi2);

        ObjectMapper mapper = new ObjectMapper();
        byte[] bytes = mapper.writeValueAsBytes(naviList);

        Map<String, Object> params = new HashMap<>();
        params.put("navigation", bytes);

        String source = "ctx._source.navigation = params.navigation";
        UpdateByQueryRequest request = new UpdateByQueryRequest("test");
        request.setScript(new Script(ScriptType.INLINE, "painless", source, params));

        client.updateByQuery(request, RequestOptions.DEFAULT);
    }
```

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [April 7, 2020, 4:08pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/4 "2020-04-07T16:08:12Z")

</div>

Could you try with `writeValueAsString` instead and log debug the generated String?

---

<div class="post-metadata">

**Author:** ![tnarita](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tnarita/32/62180_2.png) [@tnarita](https://discuss.elastic.co/u/tnarita)\
**Post date:** [April 7, 2020, 4:20pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/5 "2020-04-07T16:20:36Z")

</div>

Hi,  
I tried writeValueAsString but json string was directly inserted like below.  
There was no error log. This is very weird because If I set same json in params in Kibana like I my first post, it works perfectly. If you need additional information let me know.

```
"hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "navigation" : """{"navigationCode":["1","2","3"],"startDate":"2020-01-01T10:00:00","endDate":"2020-01-01T10:00:00"}""",
          "name" : "test name"
        }
      }
    ]
```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [May 5, 2020, 4:20pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/6 "2020-05-05T16:20:37Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [June 26, 2020, 4:03pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/7 "2020-06-26T16:03:38Z")

</div>

What happens if you print the value generated by `writeValueAsString`?

Like:

```auto
String json = mapper.writeValueAsString(naviList);
logger.info(json);

```

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [June 26, 2020, 4:03pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/8 "2020-06-26T16:03:44Z")

</div>



---

<div class="post-metadata">

**Author:** ![Danily](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/danily/32/77963_2.png) [@Danily](https://discuss.elastic.co/u/Danily)\
**Post date:** [October 27, 2020, 10:09pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/9 "2020-10-27T22:09:23Z")

</div>

Having this same issue - Serialized json looks fine before sending as a parameter in the UpdateByQuery request, but get an error on the way back

```
String serialized = objectMapper.writeValueAsString(object);
Map<String, Object> params = ImmutableMap.<String, Object>builder().put("updatedObject", serializedObject).build();
new Script(ScriptType.INLINE, "painless","ctx._source.oldField = params.updatedObject ",
    params
    );

```

When printing this query:

```
update-by-query [shared] updated with Script{type=inline, lang='painless', idOrCode='ctx._source.oldField = params.updatedObject ', options={}, params={updatedObject={"field1":"61582121-d971-4aa8-8db3-c099a688fa20","field2":"17f328af-db2b-4aa7-b6ba-3c203b305e67","field3":"some_data"}}}

```

Got this exception: `"cause":{"type":"mapper_parsing_exception","reason":"object mapping for [brandInfo] tried to parse field [brandInfo] as object, but found a concrete value"},"status":400}` making it seem like we attempted to write the object as a string value. I have verified that the type matches the mapping of the underlying index (oldField and newObject have the same json shape)

I imagine it'd be helpful if `Script` had a constructor allowing you to specify `XContentType`, similar to the Index/Update queries (`.source(bytes, XContentType.JSON)`)

Note that this works when manually creating the map, but it'd be great to be able to leverage Jackson serializers for complex/nested data types for these update scripts.

Elasticsearch verison - 7.9.1

---

<div class="post-metadata">

**Author:** ![Danily](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/danily/32/77963_2.png) [@Danily](https://discuss.elastic.co/u/Danily)\
**Post date:** [October 27, 2020, 11:22pm UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/10 "2020-10-27T23:22:20Z")

</div>

Right now I'm putting in a hack in which I expect certain indexed properties to implement a `Map<String, Object> toMap()` but this will break when moving to deeper nested objects

---

<div class="post-metadata">

**Author:** ![Danily](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/danily/32/77963_2.png) [@Danily](https://discuss.elastic.co/u/Danily)\
**Post date:** [October 28, 2020, 3:49am UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/11 "2020-10-28T03:49:01Z")

</div>

Found a solution for this - Use XContentFactory to convert the serialized string to a map as the Script expects:

```
String serializedObj = DocumentMapper.serializeObject(complexJavaPojo, objectMapper);
Map<String, Object> serializedParams =
    XContentHelper.convertToMap(
        XContentFactory.xContent(XContentType.JSON), serializedObj, false);

return new Script(
    ScriptType.INLINE,
    SCRIPT_LANG,
    String.format("ctx._source.%s = params", targetFieldPath),
    serializedParams);
```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [November 4, 2022, 7:52am UTC](https://discuss.elastic.co/t/update-by-query-dont-accept-user-defined-param-in-java-high-level-client/226927/12 "2022-11-04T07:52:40Z")

</div>


