spring-data-elasticsearch版本為4.0.0
es版本為7.6.2
項目中需要將es5.4.3升級為7.4.1。由于兩個版本的差異很大,升級需要升級jar包,重寫api。但在升級過程中遇到一個問題。
當java中某字段如下配置時

當使用ElasticsearchRestTemplate.update(updateQuery, indexCoordinates);保存數(shù)據(jù)時,如果某時間為1970-01-01 08:00:00時,其保存到es后,會存儲為0。展示如下

這時使用ElasticsearchRestTemplate.search(searchQuery, clazz);時會報錯,報錯信息如下

從報錯信息來看,缺少Integer->Date的轉(zhuǎn)換器,導致轉(zhuǎn)換失敗。
既然spring缺少轉(zhuǎn)換器,那我們添加自定義轉(zhuǎn)換器不就可以解決這個問題了嗎?
添加轉(zhuǎn)換器如下
import org.springframework.core.convert.converter.Converter;
import java.util.Date;
public class IntegerDateConverter implements Converter<Integer, Date> {
@Override
public Date convert(Integer source) {
if (source == null) {
return null;
}
return new Date(source);
}
}
轉(zhuǎn)換器注冊如下
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters" >
<set>
<bean class="com.test.web.convert.util.IntegerDateConverter"/>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"/>
然后重啟項目進行測試....
然后悲劇的發(fā)現(xiàn),還是不行.....
查看spring-data-elasticsearch源碼,發(fā)現(xiàn)如下
org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter

看到這里基本就明白問什么我們添加自定義類型轉(zhuǎn)換器后不生效了。因為我們的類型轉(zhuǎn)換器注冊到了spring容器,但是他并沒用使用spring容器中的Bean,所以壓根獲取不到我們新添加的轉(zhuǎn)換器。不得不說,這里真是坑.....
源碼中的DefaultConversionService代碼如下,可以看出器只添加了部分常用的類型轉(zhuǎn)換器。
package org.springframework.core.convert.support;
import java.nio.charset.Charset;
import java.util.Currency;
import java.util.Locale;
import java.util.UUID;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.lang.Nullable;
public class DefaultConversionService extends GenericConversionService {
@Nullable
private static volatile DefaultConversionService sharedInstance;
public DefaultConversionService() {
addDefaultConverters(this);
}
public static ConversionService getSharedInstance() {
DefaultConversionService cs = sharedInstance;
if (cs == null) {
synchronized (DefaultConversionService.class) {
cs = sharedInstance;
if (cs == null) {
cs = new DefaultConversionService();
sharedInstance = cs;
}
}
}
return cs;
}
public static void addDefaultConverters(ConverterRegistry converterRegistry) {
addScalarConverters(converterRegistry);
addCollectionConverters(converterRegistry);
converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
converterRegistry.addConverter(new StringToTimeZoneConverter());
converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());
converterRegistry.addConverter(new ObjectToObjectConverter());
converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
converterRegistry.addConverter(new FallbackObjectToStringConverter());
converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
}
public static void addCollectionConverters(ConverterRegistry converterRegistry) {
ConversionService conversionService = (ConversionService) converterRegistry;
converterRegistry.addConverter(new ArrayToCollectionConverter(conversionService));
converterRegistry.addConverter(new CollectionToArrayConverter(conversionService));
converterRegistry.addConverter(new ArrayToArrayConverter(conversionService));
converterRegistry.addConverter(new CollectionToCollectionConverter(conversionService));
converterRegistry.addConverter(new MapToMapConverter(conversionService));
converterRegistry.addConverter(new ArrayToStringConverter(conversionService));
converterRegistry.addConverter(new StringToArrayConverter(conversionService));
converterRegistry.addConverter(new ArrayToObjectConverter(conversionService));
converterRegistry.addConverter(new ObjectToArrayConverter(conversionService));
converterRegistry.addConverter(new CollectionToStringConverter(conversionService));
converterRegistry.addConverter(new StringToCollectionConverter(conversionService));
converterRegistry.addConverter(new CollectionToObjectConverter(conversionService));
converterRegistry.addConverter(new ObjectToCollectionConverter(conversionService));
converterRegistry.addConverter(new StreamConverter(conversionService));
}
private static void addScalarConverters(ConverterRegistry converterRegistry) {
converterRegistry.addConverterFactory(new NumberToNumberConverterFactory());
converterRegistry.addConverterFactory(new StringToNumberConverterFactory());
converterRegistry.addConverter(Number.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new StringToCharacterConverter());
converterRegistry.addConverter(Character.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new NumberToCharacterConverter());
converterRegistry.addConverterFactory(new CharacterToNumberFactory());
converterRegistry.addConverter(new StringToBooleanConverter());
converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverterFactory(new StringToEnumConverterFactory());
converterRegistry.addConverter(new EnumToStringConverter((ConversionService) converterRegistry));
converterRegistry.addConverterFactory(new IntegerToEnumConverterFactory());
converterRegistry.addConverter(new EnumToIntegerConverter((ConversionService) converterRegistry));
converterRegistry.addConverter(new StringToLocaleConverter());
converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new StringToCharsetConverter());
converterRegistry.addConverter(Charset.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new StringToCurrencyConverter());
converterRegistry.addConverter(Currency.class, String.class, new ObjectToStringConverter());
converterRegistry.addConverter(new StringToPropertiesConverter());
converterRegistry.addConverter(new PropertiesToStringConverter());
converterRegistry.addConverter(new StringToUUIDConverter());
converterRegistry.addConverter(UUID.class, String.class, new ObjectToStringConverter());
}
}
查看源碼org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions
發(fā)現(xiàn)其又添加了一些自定義類型轉(zhuǎn)換器,那我們是不是也可以在這里補充一下類型轉(zhuǎn)化器是不是就解決問題了?我們試試
在項目中創(chuàng)建一個包org.springframework.data.elasticsearch.core.convert。然后拷貝源碼中的類org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions到該包下。并添加我們自己的代碼
結(jié)構(gòu)如下

ElasticsearchCustomConversions類中添加代碼如下

然后在此類的最前面注冊此轉(zhuǎn)換器

由于我們重寫了源碼中的類,且包名類名都與源碼相同。根據(jù)tomcat類加載策略,優(yōu)先加載用戶自定義的類,所以我們自定義的類會生效,詳細原理參考文章:https://www.cnblogs.com/aspirant/p/8991830.html
重啟項目,測試,發(fā)現(xiàn)問題解決......