Unable to find "UpdateQueryBuilder" in springframework data 4 - spring

I am upgrading spring elasticsearch data from 3.x to 4.2.1. The support of UpdateQueryBuilder is removed from the latest version which earlier I used to construct UpdateQuery from UpdateRequest object of elasticsearch. For example:
return new UpdateQueryBuilder()
.withId(documentId)
.withClass(getDocumentClass())
.withUpdateRequest(updateRequest)
.build();
The new class UpdateQuery doesn't accept UpdateRequest object but only accepts Query. I would prefer to avoid UpdateRequest conversion to Query somehow.
Does anyone have suggestions on how to make UpdateQuery and UpdateRequest work together?

After the change from 3.2.x to 4.0 a year ago Spring Data Elasticsearch does not accept Elasticsearch classes as parameters to the API in order to constantly abstract away Elasticsearch implementation details from the SDE user.
From 4.0 on there is the nested UpdateQuery.Builder class on which you should be able to set all the parameters you did previously on the org.elasticsearch.action.update.UpdateRequest class.

Related

RestHighLevelClient parameter [include_type_name] with Elastic 8.5.1

iam trying to run spring boot application with RestHighLevelClient 7.17.4 in compatibility mod with elastic 8.5.1 by fallowing guide. When application try to call get, i've got the fallowing error:
Elasticsearch exception [type=illegal_argument_exception, reason=request [/*] contains unrecognized parameter: [include_type_name]]
My configuration of RestHighLevelClient in compatibility mod:
#Value("${hs360.services.watchlist.mgmt.elasticsearch.host}")
private String elsHost;
#Value("${hs360.services.watchlist.mgmt.elasticsearch.port}")
private int elsRestPort;
#Bean(destroyMethod = "close")
public RestHighLevelClient sourceClient() {
return new RestHighLevelClientBuilder(
RestClient.builder(new HttpHost(elsHost, elsRestPort)).setRequestConfigCallback(r -> r.setConnectTimeout(60000).setSocketTimeout(90000)).build()
).setApiCompatibilityMode(true).build();
}
and snippet, when application try to call get:
GetIndexResponse indexResponse = restHighLevelClient.indices().get(new GetIndexRequest().indices("*"), RequestOptions.DEFAULT);
From log of request i can obviously see, that request contains parameter include_type_name
org.elasticsearch.client.RestClient : request [GET http://hs360-ss-s
ource-master:9200/*?master_timeout=30s&include_type_name=true&ignore_unavailable=false&expand_wildcards=open&all
ow_no_indices=true&ignore_throttled=false] returned 1 warnings: [299 Elasticsearch-8.5.1-c1310c45fc534583afe2c1c
03046491efba2bba2 "[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consi
der cold or frozen tiers in place of frozen indices."]
I know, that this parameter is deprecated, i though compatibility mod would handle this, but obviously, there is something else. I tried to search for solution, when i can remove parameter from request, but without success.
How could i remove that parameter from request or work around this problem?
You either need to upgrade to Spring Boot 3.0 which supports ES 8.5 or downgrade Elastic to whatever your Spring Boot version supports

Couchbase modify meta data experation using Spring

When using Spring Couchbase connector I can easily get version for optimistic locking by having this in my class:
public class MyClass {
#Version
private String version;
.... rest of class omitted ....
}
I'm now trying to find a similar way to get and be able to modify the meta data for expiration. I'm unable to find how to do this.
Can someone please give an example? Thanks!
With spring data couchbase library (until the latest Version 3.0.8.RELEASE), document expiry can be defined by using #Document(expiry = 10) or #Document(expiryExpression = "${valid.document.expiry}") on the class. There is also an optional boolean attribute touchOnRead which needs to be added with #Document, which would reset the expiry timer whenever the document is directly read. Please note that currently the expiry of an existing document cannot be read/modified directly with this library. One way would be to access the below APIs exposed by Couchbase's own java SDK (com.couchbase.client.java)
getAndTouch - allows you to retrieve a document while modifying its expiration time
touch - allows you to modify a document’s expiration time without otherwise accessing the document
You can find the method signatures of the above two here : http://docs.couchbase.com/sdk-api/couchbase-java-client-2.2.4/com/couchbase/client/java/Bucket.html
The above two APIs can be accessed via the spring data couchbase library as follows
couchbaseTemplate.getCouchbaseBucket().touch(...)
couchbaseTemplate.getCouchbaseBucket().getAndTouch(...)
The getCouchbaseBucket() method of the spring library returns a reference to com.couchbase.client.java.Bucket using which the touch and getAndTouch methods can be used.

Spring Data MongoDB auto create indexes not working

I am using Spring data Mongodb v1.6.2 and Spring 4.2.1. Today I noticed that #Indexed annotation on my entities did not trigger an index creation.
The entity is annotated with org.springframework.data.mongodb.core.mapping.Document and theorg.springframework.data.mongodb.core.mapping.Document is used.
#Document
public class Entity {
#Indexed(unique= true)
private String name;
}
After some investigation it appeared that MongoPersistentEntityIndexCreator did not receive the MappingContextEvent. Spring 4.2 altered the way generics are handled for ApplicationEvents.
Spring Data MongoDB fixed this in the following commit: https://github.com/spring-projects/spring-data-mongodb/commit/2a27eb74044d6480b228a216c1f93b2b0488c59a
The issue tracker can be found here: https://jira.spring.io/browse/DATAMONGO-1224
This was fixed in all version so upgrading to 1.6.3 fixed the issue.

spring-data-elasticsearch - Jackson can't serialize using global configuration

I'm developing a project using ElasticSearch and I'm having some problems with serialization/deserialization with Jackson. My project was created using JHipster, so, I'm using spring to store my entity to the database and to index in ElasticSearch. All entities and other objects can be (de)serialized with Jackson, except when I try to add it to ES.
This is my global configuration for Jackson:
#Configuration
public class JacksonConfiguration {
#Bean
Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
SimpleModule timeModule = new JavaTimeModule();
timeModule.addSerializer(OffsetDateTime.class, JSR310DateTimeSerializer.INSTANCE);
timeModule.addSerializer(ZonedDateTime.class, JSR310DateTimeSerializer.INSTANCE);
timeModule.addSerializer(LocalDateTime.class, JSR310DateTimeSerializer.INSTANCE);
timeModule.addSerializer(Instant.class, JSR310DateTimeSerializer.INSTANCE);
timeModule.addDeserializer(LocalDate.class, JSR310LocalDateDeserializer.INSTANCE);
SimpleModule geoModule=new GeoModule();
geoModule.addSerializer(Point.class, PointSerializer.INSTANCE);
geoModule.addDeserializer(Point.class, PointDeserializer.INSTANCE);
return new Jackson2ObjectMapperBuilder()
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.findModulesViaServiceLoader(true)
.modulesToInstall(timeModule,geoModule);
}
}
This configuration works fine, except when I try add an entity to ES, for example, PointSerializer is never called. The only way I can see this serializer running (and consequently indexing correctly) for ES is adding #JsonSerialize(using = PointSerializer.class) to the field. Why is it happening and how can I configure it globally?
It seems that Spring Data elasticsearch doesn't utilize the default spring Jackson2ObjectMapperBuilder for this. Per default this configuration is used:
https://github.com/spring-projects/spring-data-elasticsearch/blob/master/src/main/java/org/springframework/data/elasticsearch/core/DefaultEntityMapper.java
... which you can overwrite by providing some custom object mapper as described here:
https://github.com/spring-projects/spring-data-elasticsearch/wiki/Custom-ObjectMapper
Here you can of course directly use your Jackson ObjectMappers. For more details, have a look at this issue at the jhipster github repo:
https://github.com/jhipster/generator-jhipster/issues/2241#issuecomment-151933768

Issue with DataSourceHealthIndicator in Spring Boot actuator

Looking at the source code for DataSourceHealthIndicator if it fails to figure out database it will use default query "SELECT 1;" to health status of the datasource.
This query fails in my environment. How can I configure HealthCheckEndpoint to use DatasourceHealthIndicator with custom query.
You can define your own HealthIndicator with name dbHealthIndicator and it will be used instead of the default, something like
#Bean
public HealthIndicator dbHealthIndicator() {
DataSourceHealthIndicator indicator = new DataSourceHealthIndicator(dataSource());
indicator.setQuery("Your Query Here");
return indicator;
}
Note that you may want to share the database type and versions that you are using and which query fit so that this can be supported out-of-the-box. Boot already does for HSQL, Derby and Oracle plus all databases that support "SELECT 1"
There is an option to configure it without any java code.
DataSourceHealthContributorAutoConfiguration takes the validation query from DataSourcePoolMetadata.
E.g. for hikari, specify property spring.datasource.hikari.connection-test-query=select 1

Resources