You need to enable JavaScript to run this app. R2DBC执行save时报错Cannot encode java.util.Date参数如何解决
优惠活动
大模型
产品
解决方案
定价
更多

R2DBC执行save时报错Cannot encode java.util.Date参数如何解决

结论

R2DBC完全支持日期类型存储,你遇到的报错是类型映射不匹配、字段对应错误、驱动使用偏差三个问题共同导致的,可按以下方案解决:

问题根因

  1. 驱动匹配错误:报错栈显示调用的是io.r2dbc.h2.codecs.DefaultCodecs,说明当前运行环境实际连接的是H2数据库而非你预期的MySQL,H2的R2DBC驱动默认未提供java.util.Date类型的编码器。
  2. 字段映射错误:实体类verificationTokenType字段对应数据库列名是verification_token_type_id,未显式指定映射会导致参数绑定错位。
  3. 旧日期API适配不足:java.util.Date是JDK1.0时代的旧日期API,R2DBC默认优先适配JSR310规范的新日期类型(LocalDateTime、Instant等),旧类型需要额外配置转换器。

解决步骤

方案一:替换为新日期API(推荐,无需额外配置)

直接将实体类中的java.util.Date类型替换为LocalDateTime,Spring Data R2DBC默认自带该类型和数据库datetime类型的映射转换器:

@Table
public class VerificationToken {

    @Id
    private final Long id;

    @Column
    private final String code;

    // 替换为LocalDateTime类型
    @Column
    private final LocalDateTime validUntil;

    @Column
    private boolean used;

    @Column("user_id")
    private Long userId;

    // 显式指定对应数据库列名
    @Column("verification_token_type_id")
    private Long verificationTokenType;
}

方案二:业务必须使用java.util.Date时自定义转换器

如果不能修改原有日期类型,可自定义读写转换器注册到R2DBC配置中:

  1. 编写转换器实现:
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.r2dbc.convert.ReadingConverter;
import org.springframework.data.r2dbc.convert.WritingConverter;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

// 写入数据库时:Date转LocalDateTime
@WritingConverter
public class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
    @Override
    public LocalDateTime convert(Date source) {
        return source.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }
}

// 读取数据时:LocalDateTime转Date
@ReadingConverter
public class LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
    @Override
    public Date convert(LocalDateTime source) {
        return Date.from(source.atZone(ZoneId.systemDefault()).toInstant());
    }
}
  1. 注册转换器到R2DBC配置:
import org.springframework.context.annotation.Configuration;
import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration;
import java.util.List;

@Configuration
public class R2dbcCustomConfig extends AbstractR2dbcConfiguration {
    @Override
    protected List<Object> getCustomConverters() {
        return List.of(new DateToLocalDateTimeConverter(), new LocalDateTimeToDateConverter());
    }
}
  1. 同样要修正实体类的字段映射注解,和方案一的字段注解保持一致。

额外校验

检查项目配置文件中的R2DBC连接地址,确认是MySQL连接地址而非H2地址,避免驱动不匹配问题:

# 示例MySQL R2DBC配置
spring:
  r2dbc:
    url: r2dbc:mysql://localhost:3306/你的库名
    username: 账号
    password: 密码

内容的提问来源于stack exchange,提问作者AleGallagher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 15:45:01