当前位置: 首页 > article >正文

SpringBoot3.3.1+Elasticsearch8.13.4日期转换踩坑实录:LocalDateTime保存为时间戳的完整方案

SpringBoot3.3.1与Elasticsearch8.13.4时间类型转换实战从踩坑到优雅解决最近在升级技术栈到SpringBoot3.3.1时发现与Elasticsearch8.13.4的集成出现了一个棘手的问题LocalDateTime类型在保存和查询时表现异常。这让我花了整整两天时间排查最终通过自定义转换器找到了解决方案。本文将详细记录这个问题的来龙去脉并提供完整的实现代码希望能帮助遇到同样困境的开发者少走弯路。1. 问题现象与背景分析在SpringBoot3.3.1强制绑定的Spring Data Elasticsearch5.3.1环境下当我们使用Field(type FieldType.Date)注解标记LocalDateTime字段时表面上数据能够正常保存但在查询时却会抛出以下异常org.springframework.data.elasticsearch.core.convert.ConversionException: Unable to convert value 2024-08-30 to java.time.LocalDateTime for property createTime通过Kibana检查ES中存储的数据发现日期确实以YYYY-MM-DD格式字符串形式存储而非Java客户端期望的时间戳或ISO格式。这种格式不匹配导致了反序列化失败。核心矛盾点ES的Date类型默认处理逻辑与Java8时间API不兼容Spring Data Elasticsearch的自动类型转换在特定版本组合下存在缺陷业务代码中广泛使用的LocalDateTime类型需要保持稳定2. 解决方案设计思路经过深入分析我们确定了三种可能的解决路径修改ES映射强制指定日期格式为ISO8601优点无需代码改动缺点依赖ES集群配置迁移成本高使用注解配置通过JsonFormat指定格式优点简单直接缺点无法解决所有场景灵活性差自定义转换器实现PropertyValueConverter接口优点完全控制转换逻辑可复用性强缺点实现复杂度稍高最终我们选择了方案3因为它提供了最大的灵活性和可控性同时不依赖外部配置。下面是具体实现细节。3. 自定义转换器完整实现我们创建一个实现了PropertyValueConverter接口的转换器类负责在LocalDateTime和时间戳之间进行双向转换package com.example.es.converter; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.data.elasticsearch.core.mapping.PropertyValueConverter; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; AutoConfiguration public class LocalDateTimeConverter implements PropertyValueConverter { private static final ZoneId ZONE_ID ZoneId.systemDefault(); Override public Object write(Object value) { if (value instanceof LocalDateTime) { return ((LocalDateTime) value).atZone(ZONE_ID).toInstant().toEpochMilli(); } throw new IllegalArgumentException(只支持LocalDateTime类型转换); } Override public Object read(Object value) { if (value instanceof Long) { return LocalDateTime.ofInstant(Instant.ofEpochMilli((Long) value), ZONE_ID); } throw new IllegalArgumentException(只支持从时间戳转换); } }关键点说明使用系统默认时区保证时间一致性write方法将LocalDateTime转为毫秒时间戳read方法将时间戳转回LocalDateTime添加类型检查确保安全转换4. 应用配置与使用示例配置完成后在实体类中的使用非常简单Document(indexName orders) public class Order { Field(type FieldType.Date) ValueConverter(LocalDateTimeConverter.class) private LocalDateTime createTime; // 其他字段... }实际效果对比场景原始行为自定义转换后数据存储2024-08-30字符串1693353600000(时间戳)数据查询转换异常正确还原为LocalDateTime索引映射date格式date格式(存储数值)5. 进阶优化与注意事项在实际应用中我们还可以进一步优化这个解决方案时区处理// 如果需要明确指定时区 private static final ZoneId UTC_ZONE ZoneId.of(UTC);日志记录Override public Object write(Object value) { log.debug(Converting {} to timestamp, value); // ...转换逻辑 }性能考虑对于高频访问的字段可以考虑缓存转换结果批量操作时注意转换器的线程安全性常见问题排查如果遇到IllegalArgumentException检查字段是否确实使用了LocalDateTime类型ES中存储的值是否为合法时间戳时间显示不一致时确认应用服务器和ES服务器的时区设置检查日志中的原始时间戳值6. 其他相关类型处理这个解决方案的模式可以扩展到其他时间类型的处理Java类型ES存储类型转换策略LocalDatedate存储为yyyy-MM-ddZonedDateTimedate存储为ISO8601字符串Instantdate存储为毫秒时间戳对于ID字段的精度问题可以采用类似的转换器方案public class LongToStringConverter implements PropertyValueConverter { Override public Object write(Object value) { return value.toString(); } Override public Object read(Object value) { return Long.parseLong((String)value); } }7. 版本兼容性考量不同版本的Spring Data Elasticsearch在处理日期类型时有显著差异版本默认行为推荐策略4.x自动转换ISO格式兼容性较好5.x严格类型检查需要显式配置6.x新的日期API需要适配在升级版本时建议全面测试时间相关字段的读写操作准备回滚方案逐步迁移避免大规模变更8. 测试验证策略为确保解决方案的可靠性应该编写全面的测试用例SpringBootTest public class DateTimeConversionTest { Autowired private ElasticsearchOperations operations; Test public void testLocalDateTimeRoundTrip() { Order order new Order(); order.setCreateTime(LocalDateTime.now()); Order saved operations.save(order); Order retrieved operations.get(saved.getId(), Order.class); assertEquals(order.getCreateTime(), retrieved.getCreateTime()); } }测试要点边界值测试(如2038年问题)时区转换测试批量操作测试空值处理测试9. 生产环境部署建议将转换器打包为独立模块方便多项目复用创建单独的starter项目es-datetime-converter-starter ├── src/main/java │ └── com/example/es/converter │ ├── LocalDateTimeConverter.java │ └── converter-auto-configuration.properties └── pom.xml在auto-configuration中注册转换器org.springframework.boot.autoconfigure.EnableAutoConfiguration\ com.example.es.converter.LocalDateTimeConverter添加版本兼容说明## 兼容性 - Spring Boot 3.3.1 - Elasticsearch 8.x10. 替代方案比较除了自定义转换器还有其他几种处理方式方案A使用String存储Field(type FieldType.Keyword) private String createTimeStr; public LocalDateTime getCreateTime() { return LocalDateTime.parse(createTimeStr); }优点简单直观缺点无法利用ES的日期计算功能方案B全局配置转换Configuration public class ElasticsearchConfig { Bean public ElasticsearchCustomConversions customConversions() { return new ElasticsearchCustomConversions(List.of( new LocalDateTimeToLongConverter(), new LongToLocalDateTimeConverter() )); } }优点统一管理缺点不够灵活方案C使用中间DTOpublic class OrderDTO { private Long createTimeMillis; public Order toEntity() { Order order new Order(); order.setCreateTime(Instant.ofEpochMilli(createTimeMillis) .atZone(ZoneId.systemDefault()) .toLocalDateTime()); return order; } }优点解耦持久化细节缺点转换逻辑分散经过实际验证自定义PropertyValueConverter在大多数场景下提供了最佳平衡点既能保持业务代码的简洁性又能精确控制存储格式。

相关文章:

SpringBoot3.3.1+Elasticsearch8.13.4日期转换踩坑实录:LocalDateTime保存为时间戳的完整方案

SpringBoot3.3.1与Elasticsearch8.13.4时间类型转换实战:从踩坑到优雅解决 最近在升级技术栈到SpringBoot3.3.1时,发现与Elasticsearch8.13.4的集成出现了一个棘手的问题:LocalDateTime类型在保存和查询时表现异常。这让我花了整整两天时间排…...

从游戏机到影音中心:用wiliwili解锁Switch的隐藏娱乐潜能

从游戏机到影音中心:用wiliwili解锁Switch的隐藏娱乐潜能 【免费下载链接】wiliwili 专为手柄控制设计的第三方跨平台B站客户端,目前可以运行在PC全平台、PSVita、PS4 和 Nintendo Switch上 项目地址: https://gitcode.com/GitHub_Trending/wi/wiliwil…...

手把手教你用Claude Desktop的MCP协议,5分钟搞定本地SQLite数据库查询

5分钟实现自然语言查询SQLite:Claude Desktop MCP协议实战指南 想象一下这样的场景:你手头有一个存储着上万条商品信息的SQLite数据库,现在需要快速统计某个品类的库存数量。传统方式可能需要打开数据库工具、编写SQL查询语句,或者…...

Czkawka:用Rust构建的开源存储清理工具全解析

Czkawka:用Rust构建的开源存储清理工具全解析 【免费下载链接】czkawka Multi functional app to find duplicates, empty folders, similar images etc. 项目地址: https://gitcode.com/GitHub_Trending/cz/czkawka 一、场景痛点:当代存储管理的…...

YOLO12开源模型合规部署:离线环境+审计日志+模型版本固化方案

YOLO12开源模型合规部署:离线环境审计日志模型版本固化方案 1. 项目背景与核心价值 YOLO12作为Ultralytics在2025年推出的最新实时目标检测模型,在保持高速推理性能的同时显著提升了检测精度。其引入的注意力机制优化了特征提取网络,nano版…...

Hunyuan-MT-7B保姆级教程:Pixel Language Portal在树莓派5上的轻量级翻译终端部署

Hunyuan-MT-7B保姆级教程:Pixel Language Portal在树莓派5上的轻量级翻译终端部署 1. 项目介绍与核心价值 Pixel Language Portal(像素语言跨维传送门)是一款基于Tencent Hunyuan-MT-7B大语言模型的创新翻译工具。与传统翻译软件不同&#…...

春季2021亚马逊研究奖获奖者公布

春季 2021 某机构研究奖获奖者公布 2021年7月,某机构通知申请人已成为2021年春季某机构研究奖的获得者。该奖项旨在为跨多个学科领域开展研究课题的学术研究人员提供无限制资金和某云平台服务积分。今天,我们正式公布26位获奖者,他们来自11个…...

收藏!小白程序员必看:Agent和工作流是最佳拍档,教你如何协同它们(附案例)

文章探讨了AI智能体(Agent)和工作流工具的关系,指出它们并非竞争对手,而是最佳拍档。Agent擅长自主决策和动态规划,适用于探索性和不确定性任务;工作流则负责流程编排和确定性执行,适用于重复性…...

保姆级教程:用Docker Compose一键部署Dify AI平台(附国内镜像加速与端口冲突解决)

零门槛部署Dify AI开发平台:Docker Compose全流程指南与避坑手册 在AI应用开发领域,快速搭建一个稳定可靠的开发环境往往是项目成功的第一步。Dify作为一款面向开发者的AI应用开发平台,通过可视化编排和低代码方式大大降低了构建基于大语言模…...

重新定义AI助手体验:突破Cursor Pro限制的5个技术方案

重新定义AI助手体验:突破Cursor Pro限制的5个技术方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your tri…...

GyroFlow:用陀螺仪数据重塑视频稳定技术

GyroFlow:用陀螺仪数据重塑视频稳定技术 【免费下载链接】gyroflow Video stabilization using gyroscope data 项目地址: https://gitcode.com/GitHub_Trending/gy/gyroflow 在数字影像创作领域,画面稳定性直接决定作品专业度。无论是运动相机拍…...

保姆级教程:用mintar版imu_utils搞定ZED2/Realsense相机内置IMU标定(避坑kalibr_allan)

保姆级教程:用mintar版imu_utils完成ZED2/Realsense相机IMU标定实战指南 当你在视觉惯性里程计(VIO)项目中遇到定位漂移问题时,很可能是因为IMU参数配置不当。与网上普遍推荐的kalibr_allan方法不同,本文将带你体验min…...

颠覆传统投资分析:TradingAgents-CN智能交易系统零门槛部署指南

颠覆传统投资分析:TradingAgents-CN智能交易系统零门槛部署指南 【免费下载链接】TradingAgents-CN 基于多智能体LLM的中文金融交易框架 - TradingAgents中文增强版 项目地址: https://gitcode.com/GitHub_Trending/tr/TradingAgents-CN 在金融科技迅猛发展的…...

不只是安装:深入理解TI毫米波雷达开发套件(MMWCAS-RF-EVM)的软件生态与数据流

不只是安装:深入理解TI毫米波雷达开发套件(MMWCAS-RF-EVM)的软件生态与数据流 毫米波雷达技术正在重塑自动驾驶、工业检测和智能安防等领域,而TI的MMWCAS-RF-EVM评估板作为行业标杆工具,其真正的价值往往被简化为"…...

【回归儿童本位,重构专业底色】学前教育行业的深度思辨与价值坚守(二)

吕坤阳亲笔二、行业高质量发展的核心:回归儿童,摒弃功利化教育随着学前教育普惠政策的推进,行业规范化程度不断提升,但功利化、形式化的教育倾向依然存在,成为高质量发展的阻碍。部分幼儿园为迎合家长“抢跑”需求&…...

3个关键步骤:如何用Bilibili-Evolved打造60fps流畅播放体验

3个关键步骤:如何用Bilibili-Evolved打造60fps流畅播放体验 【免费下载链接】Bilibili-Evolved 强大的哔哩哔哩增强脚本 项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved Bilibili-Evolved作为一款强大的哔哩哔哩增强脚本,为追求极…...

【王阳明】《泛海》

王阳明《泛海》:证道诗与心学宣言原诗险夷原不滞胸中, 何异浮云过太空? 夜静海涛三万里, 月明飞锡下天风。一、创作背景:九死一生的逃亡 这首诗写于王阳明人生最险峻的时刻,背景远比字面所呈现的更为惊心动…...

Bootstrap 下拉菜单:全面解析与应用指南

Bootstrap 下拉菜单:全面解析与应用指南 引言 Bootstrap 是一个流行的前端框架,它提供了丰富的组件和工具来帮助开发者快速构建响应式、美观的网页。其中,下拉菜单是 Bootstrap 中一个常用且重要的组件,它能够帮助用户在有限的空间…...

如何一键备份QQ空间历史说说:完整数据备份与隐私保护指南

如何一键备份QQ空间历史说说:完整数据备份与隐私保护指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 你是否担心那些记录青春的QQ空间说说会随着时间流逝而消失&#xf…...

Cosmos-Reason1-7B部署教程:Docker镜像免配置+7860端口快速启用

Cosmos-Reason1-7B部署教程:Docker镜像免配置7860端口快速启用 1. 项目概述 Cosmos-Reason1-7B是NVIDIA推出的7B参数多模态视觉语言模型(VLM),专注于物理理解和思维链推理能力。作为Cosmos世界基础模型平台的核心组件,它能够处理图像和视频…...

船舶水动力学与运动控制技术指南:从理论建模到工程实践

船舶水动力学与运动控制技术指南:从理论建模到工程实践 【免费下载链接】FossenHandbook Handbook of Marine Craft Hydrodynamics and Motion Control is an extensive study of the latest research in marine craft hydrodynamics, guidance, navigation, and co…...

5步释放Win11潜能:用Win11Debloat让系统性能提升60%的实战指南

5步释放Win11潜能:用Win11Debloat让系统性能提升60%的实战指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutte…...

3个步骤掌握Markmap:将Markdown转换为交互式思维导图完全指南

3个步骤掌握Markmap:将Markdown转换为交互式思维导图完全指南 【免费下载链接】markmap Build mindmaps with plain text 项目地址: https://gitcode.com/gh_mirrors/ma/markmap Markmap作为一款强大的开源工具,能够将普通的Markdown文本转换为直…...

ROS2开发避坑:用CycloneDDS配置文件解决本地回环通信中断问题(附完整XML)

ROS2通信稳定性实战:CycloneDDS深度配置指南 当你在机器人开发过程中遭遇节点间通信时断时续的问题,那种感觉就像在暴雨天试图用对讲机协调团队——关键指令总在最重要时刻丢失。本文将揭示如何通过CycloneDDS的精细配置,在硬件网络不稳定的…...

Ubuntu 20.04 下 Zotero 文献管理神器:从安装到插件配置的完整避坑指南

Ubuntu 20.04 下 Zotero 文献管理神器:从安装到插件配置的完整避坑指南 第一次在Linux环境下配置文献管理工具时,我盯着终端里密密麻麻的命令行输出,突然意识到学术研究的数字化工具链竟如此脆弱。直到遇见Zotero,这款跨平台的开源…...

Natapp内网穿透避坑指南:Windows系统常见报错解决方案(2024最新版)

Natapp内网穿透避坑指南:Windows系统常见报错解决方案(2024最新版) 在开发过程中,内网穿透工具如Natapp已成为连接本地开发环境与外部网络的必备利器。然而,对于初次接触Natapp的Windows用户来说,从安装配…...

如何通过技术优化提升Element Plus开发效率

如何通过技术优化提升Element Plus开发效率 【免费下载链接】element-plus 🎉 A Vue.js 3 UI Library made by Element team 项目地址: https://gitcode.com/GitHub_Trending/el/element-plus 在前端开发过程中,Element Plus作为一款基于Vue.js 3…...

打破系统壁垒:从 Android 到 macOS,打造全平台统一终端管理(MDM)方案

目录 什么是统一设备管理? 一、引言 二、为什么跨平台设备管理至关重要 三、统一设备管理平台的核心功能 3.1 多平台生态整合 3.2 全设备生命周期管理 3.3 统一策略配置 3.4 广泛的行业适用性 四、实施统一设备管理的优势 五、企业设备管理的未来趋势 六…...

用Asian Beauty Z-Image Turbo做古风头像:简单三步生成独一无二的东方美学作品

用Asian Beauty Z-Image Turbo做古风头像:简单三步生成独一无二的东方美学作品 想象一下,你的社交媒体头像不再是一张普通的自拍或卡通形象,而是一幅充满东方韵味的古风艺术作品——可能是唐代仕女的温婉,宋代文人的儒雅&#xf…...

CPU 亲和性

CPU 亲和性本质CPU 亲和性 让进程 / 线程只在指定的 CPU 核心上运行的调度约束。内核里叫:sched_affinity(调度亲和性)作用:提高 L1/L2/L3 缓存命中率减少 上下文切换(context switch)避免跨 NUMA 节点访问…...