Spring Data MongoDB auto create indexes not working - spring

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.

Related

Unable to find "UpdateQueryBuilder" in springframework data 4

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.

Is Default serialization format of Date has changed with recent Spring boot versions/Jackson Versions?

I am in the process of updating the SpringBoot version to 2.3.1.RELEASE from 2.2.2.RELEASE. Suddenly all date format of all my API responses has changed(In the timezone representation section).
From +0000 to +00:00
"timestamp": "2020-05-19T05:46:49.469+0000" - 2.2.2.RELEASE
"timestamp": "2020-06-30T09:55:23.014+00:00" - 2.3.1.RELEASE
This is my Simple POJO: I have not added any #JsonFortmat configuration for the date field.
#NoArgsConstructor
#AllArgsConstructor
#Getter
public class BuildInfo{
private String message;
private Date timestamp;
}
and my controller method
#GetMapping(value = "/buildinfo", produces = "application/json")
ResponseEntity<BuildInfo> getBuildInfo();
I have not added any serialization/ deserialization logic and I have developed only with SpringBoot's default behavior. I am trying to search any release document regarding this change, but could not find any.
Below changes, I can perform to adapt these changes
Using #JsonFormat annotation with customized pattern in every date field(but I cannot do it as this is client library)
#JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSSZ")
private Date timestamp;
Injecting Jackson2ObjectMapperBuilderCustomizer in application level.
#Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> builder.simpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
}
But I would like to narrow down the root cause for the format change? starting from which version of Jackson/Spring libraries?
It comes from jackson-databind 2.11.0.(diff)
Spring Boot 2.2.0: 2.10.0
Spring Boot 2.2.8: 2.10.4
Spring Boot 2.3.0: 2.11.0
so, it seems this behavior is Spring Boot 2.3.0 or later.
Change is documented in Spring Boot 2.3.0 RN's, in the section stating the changes in Jackson version, where it explicitly mentions "a change to the default formatting of java.util.Date and java.util.Calendar"
You can also use the following Spring Boot property to format your JSON dates: spring.jackson.date-format. Note this only works on java.util.Date and java.util.Calendar objects.

Spring Boot with Hibernate Search can't find org.hibernate.query.ParameterMetadata

I have a fairly straight forward Spring Boot 1.5.2 application using Hibernate Search. JPA stuff works just fine.
I get Caused by: java.lang.ClassNotFoundException: org.hibernate.query.ParameterMetadata when running a search.
The code looks somewhat like this. Used to run in Wildfly, but I'm migrating to Spring Boot.
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(Customer.class)
.get();
org.apache.lucene.search.Query
luceneQuery = qb.keyword()
.wildcard()
.onField("primaryParty.firstName")
.andField("primaryParty.sureName")
.andField("customerNumber")
.matching(query.trim() + "*")
.createQuery();
javax.persistence.Query jpaQuery =
fullTextEntityManager.createFullTextQuery(luceneQuery, Customer.class);
List<Customer> result = jpaQuery.getResultList();
Hibernate Core 5.0.12 is pulled in via Spring Boot, but the class is not there.
According to this: https://cia.sourceforge.io/tattleTaleReport/jar/hibernate-search-orm-5.7.0.Final.jar.html
i should expect to find it in hibernate-search-orm 5.7.0.Final. But from what I can see this jar only contains the org.hibernate.search package and no org.hibernate.query package. Can't find the class in any other package in that jar either, but it exists in a number of other packages on the class path.
Is the problem
javax.persistence.Query
If so, what to use instead? Or is the problem elsewhere?
Hibernate Search 5.7.0.Final is only compatible with Hibernate ORM 5.2.3.Final and later.
You should either:
downgrade Hibernate Search to 5.6.1.Final
or upgrade Hibernate ORM to version 5.2.3.Final or later. With Spring Boot, I'm afraid you would have to use and unstable version of Spring Boot, namely 2.0.0.BUILD-SNAPSHOT
EDIT: actually, it seems you can use Hibernate ORM 5.2+ with Spring Boot 1.5; see this sample. Be careful to use 5.2.3.Final or later, though (the sample uses 5.2.0.Final, which won't work).
By the way, the link you provided only mentions org.hibernate.query because of OSGi support, which probably isn't relevant to you. It happens that hibernate-search-orm (the module integrating Hibernate Search to Hibernate ORM) both imports and re-exports the org.hibernate.query package, but it doesn't provide it itself.
I was getting the same issue due to using 5.7.0.Final jar and it was not compatible. This issue got resolved by changing downgrade jar version.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.6.1.Final</version>

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

Need matching class for LoggersMvcEndpoint. in spring-boot 2.1.9 release

I am upgrading my project from spring-boot 1.5.12.release to 2.1.9.release. I am unable to find LoggersMvcEndpoint (https://docs.spring.io/spring-boot/docs/1.5.12.RELEASE/api/org/springframework/boot/actuate/endpoint/mvc/LoggersMvcEndpoint.html) in latest version.
In one of my controller I had this. Can some one help me to fix this.
public class LoggerController extends CloudRestTemplate {
#Autowired
LoggersMvcEndpoint loggerAPI;
#Override
public Object getFromInternalApi(final String param) {
return StringUtils.isEmpty(param) ? loggerAPI.invoke() : loggerAPI.get(param);
}
#Override
public Object postToInternalApi(final String param, final Object request) {
return loggerAPI.set(param, (Map<String, String>) request);
}
}
As per Spring docs here
Endpoint infrastructure
Spring Boot 2 brings a brand new endpoint
infrastructure that allows you to define one or several operations in
a technology independent fashion with support for Spring MVC, Spring
WebFlux and Jersey! Spring Boot 2 will have native support for Jersey
and writing an adapter for another JAX-RS implementation should be
easy as long as there is a way to programmatically register resources.
The new #Endpoint annotation declares this type to be an endpoint with
a mandatory, unique id. As we will see later, a bunch of properties
will be automatically inferred from that. No additional code is
required to expose this endpoint at /applications/loggers or as a
org.springframework.boot:type=Endpoint,name=Loggers JMX MBean.
Refer to documentation, it will help you further
and for your info LoggersMvcEndpoint was there until 2.0.0.M3 https://docs.spring.io/spring-boot/docs/2.0.0.M3/api/org/springframework/boot/actuate/endpoint/mvc/LoggersMvcEndpoint.html however there is no reference of deprecation in subsequent version's release notes of 2.0.0.M4
https://docs.spring.io/spring-boot/docs/2.0.0.M4/api/deprecated-list.html#class

Resources