调用Micronaut Repository报错Context does not contain key: io.micronaut.tx.STATUS
错误原因
这个错误是Micronaut Data R2DBC的事务上下文传播失败导致的:
- 你代码中CustomerRepository接口的
@R2dbcRepository注解被注释,Micronaut无法为该Repository生成正确的事务增强实现 - 你使用
ReactiveStreamsCrudRepository返回的是标准Publisher类型,手动用Mono.from()/Flux.from()包装时丢失了Micronaut事务需要的上下文参数 - 读写操作需要的事务上下文没有被正确初始化和传播
解决方法
按以下步骤修改即可解决:
- 打开CustomerRepository的
@R2dbcRepository注解,指定你实际使用的数据库方言,同时将父接口替换为ReactiveCrudRepository,直接返回Reactor的Mono/Flux类型,避免手动转换丢失上下文:
import io.micronaut.data.repository.reactive.ReactiveCrudRepository; import io.micronaut.data.r2dbc.annotation.R2dbcRepository; import io.micronaut.data.model.query.builder.sql.Dialect; @R2dbcRepository(dialect = Dialect.SQL_SERVER) // 替换为实际使用的数据库方言,如MYSQL、POSTGRESQL interface CustomerRepository extends ReactiveCrudRepository<Customer, Long> { @NonNull @Override Flux<Customer> findAll(); }
- 修改Controller中调用Repository的代码,移除多余的
Mono.from()包装,直接调用Repository方法:
@Controller @RequiredArgsConstructor class CustomerController { private final CustomerRepository customerRepository; @Get public Flux<Customer> getAll() { return customerRepository.findAll(); } @Get("/test") public Mono<Customer> test() { return customerRepository.findById(1L).map(e -> { System.out.println(e); return e; }); } @Post public Mono<Customer> create(@Body Customer customer) { Customer saveCustomer = new Customer(customer.getName(), customer.getSurname()); return customerRepository.save(saveCustomer); } }
- 如果还有报错,给对应的读写方法加上
@Transactional注解,显式声明事务,确保上下文正确传播:
import io.micronaut.transaction.annotation.Transactional; @Get("/test") @Transactional(readOnly = true) // 读操作可以加readOnly=true优化性能 public Mono<Customer> test() { return customerRepository.findById(1L).map(e -> { System.out.println(e); return e; }); }
- 额外确认你的配置文件中R2DBC数据源配置正确,使用r2dbc协议的连接地址,而非jdbc地址。
内容的提问来源于stack exchange,提问作者Parasite2142
相关产品推荐
相关产品推荐

