feat: Exposed R2DBC DAO#2831
Conversation
* feat: eager loading, many-to-many * feat: Complete migration of EntityTests * feat: Extract trimToFirst
R2DBC DAO API — Key Differences from JDBC DAO
This document highlights behavioral and structural differences between the JDBC DAO ( 1. Relationship properties:
|
| Method | JDBC | R2DBC |
|---|---|---|
EntityClass.findById(id) |
fun findById(id): T? |
suspend fun findById(id): T? |
EntityClass.count(op) |
fun count(op): Long |
suspend fun count(op): Long |
Entity.delete() |
fun delete() |
suspend fun delete() |
Entity.flush(batch) |
fun flush(batch): Boolean |
suspend fun flush(batch): Boolean |
Entity.refresh(flush) |
fun refresh(flush) |
suspend fun refresh(flush) |
EntityClass[id] |
operator fun get(id): T |
suspend operator fun get(id): T |
EntityClass.reload(entity) |
open fun reload(entity): T? |
suspend fun reload(entity): T? |
EntityCache.flush() |
fun flush() |
suspend fun flush() |
EntityCache.clear(flush) |
fun clear(flush) |
suspend fun clear(flush) |
Transaction.flushCache() |
fun Transaction.flushCache() |
suspend fun R2dbcTransaction.flushCache() |
Entity hook subscriptions also accept suspend lambdas:
// JDBC
EntityHook.subscribe { change -> /* non-suspend */ }
// R2DBC
EntityHook.subscribe { change -> /* suspend */ }4. Collections return SizedIterable backed by Flow
R2DBC's SizedIterable is Flow-based rather than Iterable-based. This means collecting results requires an explicit toList() call:
// JDBC
broker.clients.map { it.name } // direct iteration
// R2DBC
broker.clients().toList().map { it.name } // collect Flow, then mapThis also affects eager loading — R2DBC requires two with() overloads (one for SizedIterable, one for Iterable) where JDBC has one.
5. Explicit attach() for cross-transaction entity reuse
JDBC auto-attaches entities to the current transaction when you set a column value (inside Column.setValue). R2DBC can't do this because the auto-attach would require a suspend call inside a non-suspend operator.
R2DBC provides an explicit attach() method instead:
// R2DBC
suspendTransaction {
val broker = Broker.findById(id)!!
// ... later, in a different transaction context:
Broker.attach(broker) // explicitly re-attach
}6. Missing JDBC features (not yet ported)
The following JDBC DAO features have no R2DBC equivalent yet:
ImmutableEntityClass/ImmutableCachedEntityClass— immutable entities with cross-transaction cachingfindWithCacheCondition— cache-first lookup with fallback to DB querywarmUpReferences/warmUpOptReferences— bulk eager-loading helpers (R2DBC has equivalent private helpers but issues per-parent queries instead of bulkcompoundOrqueries for composite FKs)
|
Last time I asked you said its not usable yet or sth. How would you describe this 1? What stuff should I be aware of? Also the attachment stuff isn't clear to me yet. I didnt find a good explanation in the doc either in a quick scan. from the tutorial rn: What do I need to stay aware of if some fields of a entity could be changed while sth else still has it "cached"? |
|
Also build exposed with team city should skip detect. right now it fails with detekt weighted issues error. A Seperate detekt pipeline is good though. |
No description provided.