【无标题】

seata1.4.1版本下 

在使用mysql驱动8.0时,seata在进行undo日志处理时,JacksonUndoLogParser发生了反序列化报错。

具体错误信息如下

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"nano":356806000,"month":"APRIL","dayOfWeek":"MONDAY","dayOfYear":102,"year":2021,"monthValue":4,"dayOfMonth":12,"hour":9,"minute":31,"second":39,"chronology":{"calendarType":"iso8601","id":"ISO"}}"; line: 1, column: 2]

 原因是: 数据库类型datetime在mysql8.0会被映射为LocalDateTime类型【具体映射可查看com.mysql.jdbc.ResultSetImpl.getObject()方法】,在序列化保存到数据库后使用jackson无法反序列化

查看JacksonUndoLogParser源码后发现仅增加Timestamp类的序列化和反序列化处理,对LocalDateTime的序列化和反序列化未做处理

    private final ObjectMapper mapper = new ObjectMapper();
 
    private final SimpleModule module = new SimpleModule();
 
    public void init() {
        module.addSerializer(Timestamp.class, timestampSerializer);
        module.addDeserializer(Timestamp.class, timestampDeserializer);
        module.addSerializer(SerialBlob.class, blobSerializer);
        module.addDeserializer(SerialBlob.class, blobDeserializer);
        module.addSerializer(SerialClob.class, clobSerializer);
        module.addDeserializer(SerialClob.class, clobDeserializer);
        mapper.registerModule(module);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        mapper.enable(MapperFeature.PROPAGATE_TRANSIENT_MARKER);
    }
查看GitHub后发现已有人提出类似的问题,并且有人已经提交PR并合并到develop分支了,目前已经合并到1.4.2分支处理了。

项目中seata版本升级到1.4.2后,新建 JsonDateTimeSerializer 类

public class JsonDateTimeSerializer implements JacksonSerializer<LocalDateTime> {
 
    private static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 
    @Override
    public Class<LocalDateTime> type() {
        return LocalDateTime.class;
    }
 
    @Override
    public JsonSerializer<LocalDateTime> ser() {
        return new LocalDateTimeSerializer(DATETIME_FORMAT);
    }
 
    @Override
    public JsonDeserializer<? extends LocalDateTime> deser() {
        return new LocalDateTimeDeserializer(DATETIME_FORMAT);
    }
}
然后在 resources 目录下新建 seata/io.seata.rm.datasource.undo.parser.spi.JacksonSerializer 文件

文件内填入 JsonDateTimeSerializer 类的完整路径。

com.xxx.seata.jackson.JsonDateTimeSerializer
至此就支持  LocalDateTime 的序列化和反序列化了
————————————————
原文链接:https://blog.csdn.net/zh0134/article/details/115612416

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值