java.lang.reflect.InaccessibleObjectException:无法将字段设为私有最终瞬态 java.net.InetSocketAddress

java.lang.reflect.InaccessibleObjectException: Unable to make field private final transient java.net.InetSocketAddress

我正在尝试批量删除弹性文档,但在执行 elasticsearchOperations.delete(...) 时出现异常 "java.lang.reflect.InaccessibleObjectException: Unable to make field private final transient java.net.InetSocketAddress"。这是代码,无法弄清楚是什么原因造成的。非常感谢任何帮助。

private void deleteElasticDocuments(String catalogId) {
    List<String> docIdList = new ArrayList<>(250);
    String queryText = martServerContext.getQueryCacheInstance().getQuery(QUERY_PORTAL_GET_OBJECTS_IN_PORTAL_BY_MODEL);
    MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
    mapSqlParameterSource.addValue("cId", Integer.parseInt(catalogId));
    namedParameterJdbcTemplate.query(queryText, mapSqlParameterSource, (resultSet -> {
        int objectId = resultSet.getInt(O_ID);
        String docId = catalogId + objectId;
        docIdList.add(docId);
        if (docIdList.size() == 250) {
            Query query = new NativeSearchQueryBuilder()
                    .withQuery(QueryBuilders.idsQuery().addIds(docIdList.toArray(String[]::new)))
                    .build();
            elasticsearchOperations.delete(query, IndexCoordinates.of("portal_idx"));
            docIdList.clear();
        }
        // elasticsearchOperations.delete(docId, IndexCoordinates.of("portal_idx"));
    }));
    if (docIdList.size() < 250) {
        Query query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.idsQuery().addIds(docIdList.toArray(String[]::new)))
                .build();
        elasticsearchOperations.delete(query, IndexCoordinates.of("portal_idx"));
        docIdList.clear();
    }
}

除了查询和索引,我还添加了 Class MetadataSearch.class,现在可以正常工作了。

elasticsearchOperations.delete(query, MetadataSearch.class, IndexCoordinates.of("portal_idx"));

编辑(来自 P.J.Meisch):

让我解释一下为什么会出现此错误。您正在调用带有签名

的函数
ElasticsearchOperations.delete(Object, IndexCoordinates)

这里ElasticsearchOperations将第一个参数作为一个应该删除的实体对象,并试图找到它的id-属性。通常你会在你的情况下传递一个 MetadataSearch 的实例。 Spring 数据 Elasticsearch 已经从初始设置中知道该对象具有哪些属性。

但现在它得到一个 NativeSearchQuery 的对象,它不被称为实体类型,因此 Spring Data Elasticsearch 分析对象及其属性,这归结为属性属性 ...

NativeSearchQuery 有一个 属性 类型 RequestBuilder,它有一个 SearchRequest,它又包含一个 TransportAddress,它有一个 InetSocketAddress.此处检查失败并出现您看到的错误。

所以确实使用 delete 变体进行查询,实体 class 和 IndexCoordinates 是正确的方法。如果你的 MetadataSearch class 被注释为 @Document(indexName="portal_idx") 你可以省略最后一个参数。