Skip to content
Bluetape4k docs1.11

Insert, update, and delete

Latest stable Based on Bluetape4k release 1.11.0

insertSuspending(entity) runs Spring Data’s insert<T>().using(entity) and returns the stored entity. Generated IDs can be read from the result when mapping supports them.

val saved = operations.insertSuspending(
Post(title = "R2DBC", content = "Coroutine extensions")
)
checkNotNull(saved.id)

insertOrNullSuspending returns null only if the publisher completes without a value. It does not convert constraint or mapping failures to null.

The module has no save operation that chooses insert or update from entity state. Passing an existing ID to insertSuspending does not imply an update. Express updates with Query and Update.

val query = Query.query(Criteria.where(Post::id.name).isEqual(postId))
val changes = Update.update(Post::title.name, "Updated")
val updated: Long =
operations.updateSuspending<Post>(query, changes)

The result is the affected row count. For an ID query, updated == 0L means the target was absent or no longer matched. Validate the count when exactly one row was expected.

Use deleteSuspending<T>(query) for conditional deletion and deleteAllSuspending<T>() for all rows.

val deleted = operations.deleteSuspending<Post>(query)
if (deleted != 1L) {
throw PostNotFoundException(postId)
}

deleteAllSuspending delegates with Query.empty(). Reserve it for explicit cases such as fixture cleanup, and add safeguards before using it in production code.

Each extension delegates one write to the supplied Spring Data operation; it does not start a transaction. If a post and its first comment must commit together, place both calls in one service-level reactive transaction.

Follow the application’s transaction policy. Creating separate transactions around each repository function cannot provide atomicity for a larger business operation.

  • Duplicate-key and foreign-key violations propagate from the driver and Spring Data.
  • Entity-to-row conversion failures propagate as mapping errors.
  • Connection acquisition failure and timeout are not hidden.
  • Coroutine cancellation is not converted to success or 0L.
  • A normal zero-row update or delete remains distinct from an exception.

Retry outside the transaction only after the complete operation is known to be idempotent.

R2dbcEntityOperationsExtensionsTest inserts a Post, checks its generated ID, updates the title by ID, reloads it, deletes it, and finally verifies existsSuspending is false. Connecting each affected count to the next state assertion makes it a useful minimal example.

Continue to Queries and repositories.