0

I'm using Elasticsearch 8.6.2 version with spring boot 2.7.12 for doing a CRUD application over an index in elasticsearch.

Configuration class:

@Configuration
public class ConfigElasticSearch {

  @Value("${elasticsearch.url}")
  private String urlElasticsearch;

  @Value("${elasticsearch.user}")
  private String userElasticsearch;

  @Value("${elasticsearch.pwd}")
  private String pwdElasticsearch;

  @Bean
  public RestHighLevelClient client() {
    ClientConfiguration clientConfiguration = ClientConfiguration.builder()
        .connectedTo(urlElasticsearch)
        .withBasicAuth(userElasticsearch, pwdElasticsearch)
        .build();
    return RestClients.create(clientConfiguration).rest();
  }

  @Bean
  public ElasticsearchOperations elasticsearchTemplate() {
    return new ElasticsearchRestTemplate(client());
  }
}

I have my entity class:

@Document(indexName = "empleadosindex", shards = 1, replicas = 0)
public class EmpleadoEntity {

  public EmpleadoEntity() {
    super();
  }

  @Id
  private String id;

  @Field(type = FieldType.Text, name = "dni")
  private String dni;

  @Field(type = FieldType.Text, name = "nombre")
  private String nombre;

  @Field(type = FieldType.Long, name = "telefono")
  private Long telefono;

Also, my interface for spring-data:

@Repository
public interface EmpleadoRepository extends ElasticsearchRepository<EmpleadoEntity, 
String> {
}

My pom is using spring boot starter 2.7.12, with this dependency for elasticsearch:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

If I execute findById() or findAll(), it works and returns the proper information stored in elasticsearch.

But if I execute save(entity), it fails returning an exception, but the content of the document is stored in elastisearch.

The error that I got is:

    org.springframework.dao.DataAccessResourceFailureException: Unable to parse 
response body for Response{requestLine=POST /clientindex/_doc?timeout=1m HTTP/1.1, 
host=http://localhost:9200, response=HTTP/1.1 201 Created}; nested exception is 
java.lang.RuntimeException: Unable to parse response body for 
Response{requestLine=POST /clientindex/_doc?timeout=1m HTTP/1.1, 
host=http://localhost:9200, response=HTTP/1.1 201 Created}
  at org.springframework.data.elasticsearch.core.ElasticsearchExceptionTranslator.translateExceptionIfPossible(ElasticsearchExceptionTranslator.java:94)
  at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.translateException(ElasticsearchRestTemplate.java:601)
  at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.execute(ElasticsearchRestTemplate.java:584)
  at org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate.doIndex(ElasticsearchRestTemplate.java:187)
  at org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate.save(AbstractElasticsearchTemplate.java:201)
  at org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository.lambda$save$6(SimpleElasticsearchRepository.java:188)
  at org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository.executeAndRefresh(SimpleElasticsearchRepository.java:360)
  at org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository.save(SimpleElasticsearchRepository.java:188)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)
  at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
  at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
  at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:530)
  at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:286)
  at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:640)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:164)
  at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:139)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:220)
  at jdk.proxy2/jdk.proxy2.$Proxy124.save(Unknown Source)

Can anyone help me to discover why is happening this error when reading response from elasticsearch when calling to save() method?

Thank you in advance!

Best regards!

2 Answers2

0

See my answer at https://stackoverflow.com/a/76396961/4393565

Do you set the Elasticsearch compatibility headers in your requests? This error normally is seen when The Elasticsearch 8 server sends an answer in a format not understood by the 7 client (and setting the headers does not guarantee it's working).

The best thing is to either stay on Boot 2.7 and use an Elasticsearch 7 instance, or upgrade to the current version of Spring Boot - or at least to 3.0

P.J.Meisch
  • 18,013
  • 6
  • 50
  • 66
0

Thank you @PJ.Meisch! I have set headers and it works fine:

 HttpHeaders compatibilityHeaders = new HttpHeaders();
  compatibilityHeaders.add("Accept", "application/vnd.elasticsearch+json;compatible-with=7");
  compatibilityHeaders.add("Content-Type", "application/vnd.elasticsearch+json;" + "compatible-with=7");
Carlos
  • 1