Spring Data R2DBC
Reactive relational database access for Spring applications — Spring Data abstractions (repositories, templates) over R2DBC (Reactive Relational Database Connectivity), the non-blocking alternative to JDBC. Spring Data R2DBC provides: ReactiveCrudRepository with Flux<T>/Mono<T> return types, R2dbcEntityTemplate for fluent query building, @Query annotation for custom SQL, and Spring Boot auto-configuration. Supports PostgreSQL (r2dbc-postgresql), MySQL (r2dbc-mysql), MariaDB, SQL Server, H2, and Oracle. Designed for Spring WebFlux reactive stacks where blocking JDBC would block event loop threads. No JPA/Hibernate — intentionally limited ORM (no lazy loading, no relationship management) for simplicity.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
Parameterized queries prevent SQL injection. TLS for database connections via r2dbc URL ssl parameter. Credentials via Spring Boot environment/secrets. No JPA caching layer — each query hits database directly, reducing stale data risk for agent services.
⚡ Reliability
Best When
You're building a Spring WebFlux agent service that queries a relational database and need non-blocking database access to avoid starving the event loop — R2DBC provides familiar Spring Data APIs with reactive execution.
Avoid When
You're using Spring MVC, your team isn't comfortable with Project Reactor, you need JPA features like lazy loading, or you're using Spring Boot with virtual threads (Loom) where blocking JDBC is acceptable.
Use Cases
- • Build non-blocking Spring WebFlux agent APIs with reactive PostgreSQL access — R2DBC repository returns Flux<Agent> instead of blocking List<Agent> for agent data endpoints
- • Implement reactive agent event sourcing with Spring Data R2DBC — write agent events to PostgreSQL reactively using R2dbcEntityTemplate.insert() returning Mono<AgentEvent>
- • Reactive agent repository with custom SQL — @Query annotation with Spring Data R2DBC for complex agent filtering queries that return Flux<AgentDto> without blocking Spring WebFlux thread pool
- • Batch insert agent data reactively — R2dbcEntityTemplate.insertAll() with Flux<Agent> input for bulk agent record creation without blocking threads
- • Paginate agent results reactively — ReactiveSortingRepository with Pageable returns Flux<Agent> slice for reactive agent browsing APIs
Not For
- • Spring MVC (blocking) applications — R2DBC reactive types add complexity with no benefit in blocking Spring MVC; use Spring Data JPA with HikariCP for blocking Spring apps
- • Complex ORM with relationships — R2DBC intentionally has no lazy loading or relationship management; use Spring Data JPA or jOOQ for complex agent domain models with multiple table joins
- • Teams new to reactive programming — reactive SQL with Flux/Mono is significantly more complex than blocking JPA; ensure team understands Project Reactor before adopting R2DBC for agent services
Interface
Authentication
Database access library — no auth concepts. Database credentials configured via spring.r2dbc.url, username, password properties or environment variables. Connection pool managed by R2DBC connection factory.
Pricing
Spring Data R2DBC is Apache 2.0 licensed, maintained by Broadcom/VMware. Free for all use.
Agent Metadata
Known Gotchas
- ⚠ No lazy loading — R2DBC has no JPA-style lazy loading; @OneToMany relationships are not managed; fetch related entities explicitly with separate queries and combine with Mono.zip() or flatMap(); agent domain models need explicit join queries
- ⚠ @Transactional requires reactive transaction manager — Spring's @Transactional works with R2DBC but requires ReactiveTransactionManager bean; mixing blocking TransactionManager with reactive code causes transactions to not apply
- ⚠ R2DBC connection pool is separate from JDBC pool — if using both R2DBC and JDBC in same app, configure both r2dbc-pool and HikariCP; sharing connections between R2DBC and JDBC is not supported
- ⚠ Kotlin coroutines integration requires co-routines extension — add spring-data-r2dbc Kotlin extension for coroutine-friendly suspend functions and Flow<T> instead of Flux<T>; without extension, must manually handle Mono/Flux in suspend contexts
- ⚠ Custom queries return Map not entities by default — @Query methods returning non-entity types need explicit RowMapper or projection interface; @Query without mapped return type returns Flux<Map<String, Object>> which requires manual mapping for agent DTOs
- ⚠ Spring Data R2DBC lacks @OneToMany — no relationship mapping; complex agent queries with joins must use R2dbcEntityTemplate.select() with custom SQL or R2dbcEntityTemplate join queries; ORM comfort of JPA is intentionally absent
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for Spring Data R2DBC.
Scores are editorial opinions as of 2026-03-06.