I am new on ElasticSearch, and I would like to have a Spring Boot Application that connects to a database ElasticSearch 8.6, in order to do CRUD operations over an index. I was trying to do a CRUD application using Spring Boot with ElasticSearch database.
Entity:
@Document(createIndex = true, indexName = "client")
public class ClientEntity {
public ClientEntity() {
super();
}
@Id
private String id;
@Field(type = FieldType.Text, name = "name")
private String name;
@Field(type = FieldType.Long, name = "phoneNumber")
private Long phone;
The repository interface from spring data is:
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ClientRepository extends ElasticsearchRepository<ClientEntity, String> {
}
Elastic search config:
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder.HttpClientConfigCallback;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
@Configuration
public class ConfigElasticSearch extends ElasticsearchConfiguration {
@Bean
public ElasticsearchTransport getElasticsearchTransport() {
return new RestClientTransport(getRestClient(), new JacksonJsonpMapper());
}
@Bean
public ElasticsearchClient getElasticsearchClient() {
ElasticsearchClient client = new ElasticsearchClient(getElasticsearchTransport());
return client;
}
@Override
public ClientConfiguration clientConfiguration() {
return ClientConfiguration.builder().connectedTo("localhost:9200")
.withBasicAuth("user", "my-password").build();
}
pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.12</version>
</parent>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
<json-web-token.version>0.9.1</json-web-token.version>
<org-modelmapper.version>3.1.1</org-modelmapper.version>
</properties>
<dependencies>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>${org-modelmapper.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- ES -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
The service that uses the Spring Data repository is the following:
@Service("clientPersistence")
public class ClientPersistenceElasticSearchDb {
@Autowired
private ClientRepository clientRepository;
public Stream\<ClientEntity\> findAll() {
return StreamSupport.stream(this.clientRepository.findAll().spliterator(), false);
}
public Optional\<ClientEntity\> findById(String id) {
return clientRepository.findById(id);
}
}
The main configuration for my microservice is:
@SpringBootApplication
public class ClientMicroserviceApplication {
public static void main(String[] args) {
SpringApplication.run(EmpleadosMicroservicioApplication.class, args);
}
}
If I start my microservice, I get the following when starting (and then, the microservice hangs):
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'clientPersistencia': Unsatisfied dependency expressed through field 'clientRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'clientRepository' defined in es.clientmicroservice.dao.clientRepository defined in @EnableElasticsearchRepositories declared on ConfigElasticSearch : Cannot resolve reference to bean 'elasticsearchTemplate' while setting bean property 'elasticsearchOperations'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'elasticsearchOperations' defined in class path resource [es/clientmicroservice/config/ConfigElasticSearch .class]: Unsatisfied dependency expressed through method 'elasticsearchOperations' parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elasticsearchClient' defined in class path resource [es/clientmicroservice/config/ConfigElasticSearch .class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [co.elastic.clients.elasticsearch.ElasticsearchClient]: Factory method 'elasticsearchClient' threw exception; nested exception is java.lang.NoClassDefFoundError: jakarta/json/spi/JsonProvider
I don't know why my class clientPersistence is not build because missing JsonProvider dependency.
Any one could help me?
Thank you in advance!!