Spring Boot 1.4迁移至2.0.0:如何处理存储为字节数组的LocalDateTime?
解决Spring Boot 2.0迁移中Hibernate读取Blob存储的LocalDateTime/LocalDate报错问题
我之前做类似版本迁移时也踩过这个坑,核心原因是Hibernate 5.2+(Spring Boot 2.0默认依赖版本)对Java 8日期类型的处理逻辑和旧版本完全不同:
在Spring Boot 1.4 + Hibernate 5.0时期,LocalDateTime/LocalDate如果没显式指定类型,会默认被序列化为Java对象存在Blob字段里;而Hibernate 5.2+开始,默认会把这些类型直接映射成SQL的TIMESTAMP/DATE类型,启动后它会把原来Blob里的序列化字节当成timestamp字符串去解析,自然就抛出"Trailing junk on timestamp:"这类解析错误。
下面给你两种可行的解决方案,你可以根据需求选择:
方案一:保留原有Blob存储方式(快速兼容)
如果暂时不想修改数据库数据,只需要在实体类对应的日期字段上显式指定Hibernate用序列化类型处理:
import org.hibernate.annotations.Type; import javax.persistence.Column; import java.time.LocalDateTime; // ... @Column(columnDefinition = "BLOB") @Type(type = "serializable") private LocalDateTime createTime; @Column(columnDefinition = "BLOB") @Type(type = "serializable") private LocalDate createDate;
加上@Type(type = "serializable")注解后,Hibernate就会回到原来的序列化/反序列化逻辑,能正确读取Blob里的Java对象字节。
方案二:迁移到标准SQL日期类型(长期推荐)
如果想贴合Hibernate 5.2+的最佳实践,建议把数据迁移到标准的TIMESTAMP/DATE字段,步骤如下:
- 备份数据库:先做好全量备份,避免数据丢失。
- 数据迁移脚本:编写脚本把Blob字段里的序列化对象反序列化为日期值,更新到新的TIMESTAMP/DATE字段(或者直接覆盖原字段,务必先备份)。
- 修改实体类:去掉
@Type(type = "serializable")注解,Spring Boot 2.0已经自动配置了Hibernate对Java 8日期类型的支持,不需要额外依赖,直接用默认映射即可:@Column(columnDefinition = "TIMESTAMP") private LocalDateTime createTime; @Column(columnDefinition = "DATE") private LocalDate createDate;
额外注意事项
- 确认项目中没有自定义的Hibernate类型配置干扰默认行为,比如
application.properties里的spring.jpa.properties.hibernate.type.*相关属性,如有冲突需要调整。 - 测试时先在本地/测试环境验证,确保数据读写正常后再推到生产。
内容的提问来源于stack exchange,提问作者abarraford
相关产品推荐
相关产品推荐

