Reputation: 127
Hi im trying to delete user by his id from a table in Postgres database.
Im using Spring and R2DBC and trying to use DatabaseClient.execute("sqlCommand")
for my custom delete query:
import org.springframework.data.r2dbc.core.DatabaseClient;
@Service
@Transactional
public class CustomSqlService {
private final DatabaseClient databaseClient;
public Mono<Void> deleteWithCustomSql(String sql) {
databaseClient.execute(sql)
return Mono.empty();
}
Where sql
is "DELETE FROM user_table WHERE user_id = 1;"
Method in the Controller:
@RestController
@RequestMapping("postgres/")
@Timed
public class PostgresController {
// omitted code
@DeleteMapping(path = "/delete_user/{userId}")
public Mono<Void> deleteUser(@PathVariable("userId") Long userId) {
return customSqlService.deleteWithCustomSql("DELETE FROM user_table WHERE user_id = " + userId);
}
But when I test it, command is not working. When i debug i can see there's MonoOnResumeError
in the result from .execute()
.
I have other methods that perform insert
and select
statements in the same fashion and they work well.
The test I have for it:
@Test
void shouldDeleteDataFromTable() {
User user = User.builder()
.userId(1L)
.sessionId(2L)
.timestamp(10L)
.build();
webTestClient
.post()
.uri("/postgres/save_user")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(Mono.just(user), User.class)
.exchange()
.expectStatus().isOk()
webTestClient
.delete()
.uri("/postgres/delete_user/1")
.exchange()
.expectStatus()
.isOk();
userRepository.findAll().take(1).as(StepVerifier::create)
.expectNextCount(0)
.verifyComplete();
How to correctly use databaseClient.execute()
for custom delete query in PostgreSQL ?
Upvotes: 0
Views: 2639
Reputation: 9301
Hope you are using the latest R2dbc 1.0 and Spring Data R2dbc(managed by Spring Boot 3.0).
Your method deleteWithCustomSql
does not work. There is no subscription on the databaseCLient.exectue
, the sql is never be executed and return a result.
Try to change to the following, move sql here, and use bind
to bind a parameter to sql.
public Mono<Long> deleteByUserId(Long userId) {
return databaseClient.sql("DELETE FROM user_table WHERE user_id = :userId")
.bind("userId", userId)
.fetch()
.rowsUpdated();
}
In the controller, changed to the following.
@DeleteMapping(path = "/users/{userId}")
public Mono<ResponseEntity> deleteUser(@PathVariable("userId") Long userId) {
return customSqlService.deleteByUserId(userId)
.map(deleted -> {
if(deleted>0) return noContent().build();
else return notFound().build();
});
}
Check my working example of delete
operations, which demonstrates how to bind a parameter in sql, it is based on the latest Spring Data R2dbc/Postgres.
Upvotes: 1