Spring Boot+WebFlux+Kotlin:订阅Mono内的CRUD操作失败
WebFlux + Kotlin + PostgreSQL 数据入库失败排查方案
1. 响应式事务配置检查
- 必须使用Reactive专属事务注解:
@Transactional(transactionManager = "reactiveTransactionManager"),普通@Transactional在WebFlux环境下不生效。 - 确认配置类中已正确定义
ReactiveTransactionManagerBean:@Bean fun reactiveTransactionManager(connectionFactory: ConnectionFactory): ReactiveTransactionManager { return R2dbcTransactionManager(connectionFactory) }
2. 响应式数据流订阅检查
- WebFlux的
Mono/Flux是懒加载的,未订阅则不会执行实际数据库操作:- 错误示例:调用
saveAll()后未返回或订阅fun saveData(posts: List<Post>) { postRepo.saveAll(posts) // 无订阅,操作不执行 } - 正确做法:返回
Flux<Post>或Mono<Void>交由控制器自动订阅,或内部添加subscribe()(需处理异常):fun saveData(posts: List<Post>): Flux<Post> { return postRepo.saveAll(posts) .doOnError { log.error("保存失败: ${it.message}") } }
- 错误示例:调用
3. 实体类映射验证
- 主键配置:确认
@Id和@GeneratedValue(如GenerationType.IDENTITY)正确标注,PostgreSQL自增主键需对应数据库列类型为serial或bigserial。 - 字段映射:检查
@Column名称与数据库列名一致,或开启驼峰转下划线配置:spring: r2dbc: properties: hibernate: naming: physical-strategy: org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy - 类型匹配:实体类字段类型需与数据库列类型对应(如
Long对应bigint)。
4. 响应式仓库接口确认
- 仓库必须继承
ReactiveCrudRepository或ReactiveJpaRepository,而非普通CrudRepository:interface PostRepository : ReactiveCrudRepository<Post, Long>
5. 数据库连接配置校验
- 确保使用R2DBC连接(WebFlux推荐非阻塞驱动),依赖及配置示例:
- 构建脚本添加依赖:
implementation 'io.r2dbc:r2dbc-postgresql' implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc' - 配置文件:
spring: r2dbc: url: r2dbc:postgresql://localhost:5432/your_db username: your_user password: your_pass data: r2dbc: repositories: enabled: true
- 构建脚本添加依赖:
- 确认数据库已创建,表结构与实体类匹配(可通过
spring.r2dbc.hibernate.ddl-auto=create自动生成表测试)。
6. 异常日志排查
- 调整日志级别为
DEBUG,查看数据库操作相关日志:logging: level: org.springframework.r2dbc: DEBUG io.r2dbc.postgresql: DEBUG - 在数据流中添加异常捕获,明确错误原因:
postRepo.save(post) .doOnError { e -> log.error("保存失败详情: ", e) }
7. 主键冲突验证
- jsonplaceholder返回的数据主键可能已存在于数据库中,导致
save()执行更新而非插入。可清空表后重新测试,或使用insert()方法(部分仓库支持)强制插入,观察是否抛出主键冲突异常。
内容的提问来源于stack exchange,提问作者aha001
相关产品推荐
相关产品推荐

