Spring Data R2DBC连接多PostgreSQL库时自定义转换器未生效问题
问题根因
Spring Data R2DBC 的R2dbcCustomConversions、MappingR2dbcConverter等转换组件是和数据源对应的R2dbcEntityTemplate绑定的,属于数据源级别的配置。你仅给第一个数据源的操作模板注册了MyData和JSON互转的自定义规则,第二个数据源对应的操作模板未挂载自定义转换器,框架无法识别MyData是需要序列化的普通POJO,才会误判为嵌套实体抛出异常。
解决方案
1. 提取公共转换器生成逻辑
先写公共方法统一生成自定义转换器,避免两个数据源重复编码:
// 公共方法:生成包含MyData<->JSON转换规则的自定义转换器 private R2dbcCustomConversions buildR2dbcCustomConversions() { List<Object> converters = new ArrayList<>(); // 写转换器:MyData转PG的Json类型 converters.add((Converter<MyData, Json>) source -> Json.of(JacksonUtil.toJsonString(source))); // 读转换器:PG的Json类型转MyData converters.add((Converter<Json, MyData>) source -> JacksonUtil.parse(source.asString(), MyData.class)); return R2dbcCustomConversions.of(PostgresDialect.INSTANCE, converters); }
2. 给第二个数据源手动配置带转换器的操作模板
不要只配置基础连接工厂,需要完整配置R2dbcEntityTemplate并绑定自定义转换器:
@Configuration public class SecondPostgresConfig { // 配置第二个库的连接工厂 @Bean @Qualifier("secondConnectionFactory") public ConnectionFactory secondConnectionFactory() { return PostgresConnectionFactory.builder() .host("你的第二个库地址") .port(5432) .database("库名") .username("账号") .password("密码") .build(); } // 配置带自定义转换器的第二个库操作模板 @Bean @Qualifier("secondR2dbcEntityTemplate") public R2dbcEntityTemplate secondR2dbcEntityTemplate( @Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory) { R2dbcCustomConversions customConversions = buildR2dbcCustomConversions(); // 构建映射上下文,注册自定义类型规则 R2dbcMappingContext mappingContext = new R2dbcMappingContext(); mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); // 构建带自定义转换规则的转换器 MappingR2dbcConverter converter = new MappingR2dbcConverter( mappingContext, RelationResolver.NopRelationResolver.INSTANCE, customConversions ); return new R2dbcEntityTemplate(connectionFactory, PostgresDialect.INSTANCE, converter); } // 如果第二个库需要用Repository接口操作,额外加此配置指定对应模板 @Configuration @EnableR2dbcRepositories( basePackages = "你的第二个库Repository所在包路径", entityOperationsRef = "secondR2dbcEntityTemplate" ) public class SecondRepositoryConfig { } }
注意事项
- 两个数据源的
R2dbcEntityTemplate都要绑定自定义转换器,不要直接用默认构造的模板,默认模板不会加载你的自定义转换规则 - 你使用的
r2dbc-postgresql 0.8.8.RELEASE属于旧版本,建议搭配Spring Boot 2.4.x~2.6.x版本使用,避免版本不兼容导致转换器失效 - 如果后续
LocalDateTime也出现序列化异常,可以在转换器列表中补充对应时间类型的转换规则,或者升级r2dbc-postgresql到1.x+版本,新版对JSR310时间类型的原生支持更完善
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

