spring-data-elasticsearch4.0.0查詢時間戳報錯

spring-data-elasticsearch版本為4.0.0
es版本為7.6.2

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


image.png

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


image.png

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

從報錯信息來看,缺少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


image.png

看到這里基本就明白問什么我們添加自定義類型轉(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)如下

image.png

ElasticsearchCustomConversions類中添加代碼如下
image.png

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

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

重啟項目,測試,發(fā)現(xiàn)問題解決......

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,275評論 6 342
  • 核心概念 Repository Repository 是Spring Data 的核心接口 。 它將domai...
    金剛_30bf閱讀 7,664評論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評論 19 139
  • 翻譯自官方文檔英文版,有刪減。 BioMed Central Development Team version 2...
    liycode閱讀 23,646評論 0 18
  • 前言 在剖析完 「Spring Boot 統(tǒng)一數(shù)據(jù)格式是怎么實現(xiàn)的? 」文章之后,一直覺得有必要說明一下 Spri...
    日拱一兵閱讀 573評論 0 8

友情鏈接更多精彩內(nèi)容