JDK8对LocalDateTime在Redis中反序列化失败问题

报错:

Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2019-10-21 13:57:38')
 at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: java.util.ArrayList[0]->com.construn.vehicle.tmrp.entity.IncomeSummaryRepInfo["createTime"]) 
java.lang.IllegalArgumentException: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('2019-10-21 13:57:38')
 at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: java.util.ArrayList[0]->com.construn.vehicle.tmrp.entity.IncomeSummaryRepInfo["createTime"])

在线上发现的这个问题,大概意思是对LocalDataTime反序列化错误。在本地也有这个问题,我本地和线上的配置、分支都是一样的,所以先排除是环境问题。

刚开始比较奇怪的是用postman对其请求,第一次成功,后面几次就都报错了。查找问题的时候上网查过,大家都说是对redis操作的时候LocalDataTime类型反序列化处理错误,但是我好像没有看到有对redis数据库进行操作,后来发现是@Cacheable这个注解搞的鬼

后来终于发现了错误,报错原因是mappe中的接口加了@Cacheable(cacheNames = FillCacheConstants.CORE_EMP_CACHE_NAME, unless = "#result == null ")这个注解,这个注解会在每次对数据库进行操作的时候,参数一样的前提下,先去redis查看有没有这个数据的缓存,如果有的话就从缓存里拿,没有的话就才会对数据库进行操作。

第一次请求的时候,程序进入redis发现没有这部分数据,就会向数据库请求,这时候对localdatatime的转化没有问题。问题出在后续的请求,后续请求程序进入redis缓存,发现有这个数据,就会把数据从redis反序列化出来,但是这时候因为实体类里面有localdatatime这个类型,而redis对jdk8的这个类型处理有问题,所以会报错

解决方法:
1.如果实体类中没有用到LocalDateTime类型的这个数据,可以换一个实体类,把.LocalDateTime去掉

2.如果要用到LocalDateTime这个类型的数据,可以在其上面添加 @JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonSerialize(using = LocalDateTimeSerializer.class)的注解,也可以解决问题

3.在项目的redis配置类里面, redisCacheTemplate在会有一个配置,template.setValueSerializer(new GenericJackson2JsonRedisSerializer());,GenericJackson2JsonRedisSerializer是spring提供的一个默认类,把GenericJackson2JsonRedisSerializer换成其他的类也可以(具体需要你去去另外百度一下,我不打算用这个方法所以没去查),但是可能会牵扯到项目的其他用到redis的地方,所以需要用前需要思考一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值