From 4801a4fbc25353e3ddd02f611fb91ca17e5dbdbf Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 22 Nov 2019 15:53:20 +0100 Subject: [PATCH] =?UTF-8?q?#232=20-=20Guard=20Repository.save(=E2=80=A6)?= =?UTF-8?q?=20with=20provided=20Id=20with=20TransientDataAccessException?= =?UTF-8?q?=20if=20row=20does=20not=20exist.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now emit a TransientDataAccessException if an object with a provided Id yields no affected rows. Such an arrangement is typically an indicator for a bug where calling code expects the object to be inserted with a provided Id. --- .../repository/support/SimpleR2dbcRepository.java | 15 ++++++++++++--- .../H2SimpleR2dbcRepositoryIntegrationTests.java | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepository.java b/src/main/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepository.java index 55fe9b4d2..55c668ca4 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepository.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepository.java @@ -15,7 +15,6 @@ */ package org.springframework.data.r2dbc.repository.support; -import org.springframework.transaction.annotation.Transactional; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -24,6 +23,7 @@ import java.util.List; import org.reactivestreams.Publisher; +import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.data.r2dbc.convert.R2dbcConverter; import org.springframework.data.r2dbc.core.DatabaseClient; import org.springframework.data.r2dbc.core.PreparedOperation; @@ -37,6 +37,7 @@ import org.springframework.data.relational.core.sql.Table; import org.springframework.data.relational.core.sql.render.SqlRenderer; import org.springframework.data.relational.repository.query.RelationalEntityInformation; import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; /** @@ -83,8 +84,16 @@ public class SimpleR2dbcRepository implements ReactiveCrudRepository { + + if (rowsUpdated == 0) { + sink.error(new TransientDataAccessResourceException( + String.format("Failed to update table [%s]. Row with Id [%s] does not exist.", + this.entity.getTableName(), this.entity.getId(objectToSave)))); + } else { + sink.next(objectToSave); + } + }); } /* (non-Javadoc) diff --git a/src/test/java/org/springframework/data/r2dbc/repository/support/H2SimpleR2dbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/repository/support/H2SimpleR2dbcRepositoryIntegrationTests.java index 8536936f5..82b5a0f39 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/support/H2SimpleR2dbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/support/H2SimpleR2dbcRepositoryIntegrationTests.java @@ -29,6 +29,7 @@ import org.junit.runner.RunWith; import org.springframework.context.annotation.Configuration; import org.springframework.dao.DataAccessException; +import org.springframework.dao.TransientDataAccessException; import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration; import org.springframework.data.r2dbc.testing.H2TestSupport; import org.springframework.test.context.ContextConfiguration; @@ -82,4 +83,18 @@ public class H2SimpleR2dbcRepositoryIntegrationTests extends AbstractSimpleR2dbc Map map = jdbc.queryForMap("SELECT * FROM legoset"); assertThat(map).containsEntry("name", "SCHAUFELRADBAGGER").containsEntry("manual", 12).containsKey("id"); } + + @Test // gh-232 + public void updateShouldFailIfRowDoesNotExist() { + + LegoSet legoSet = new LegoSet(9999, "SCHAUFELRADBAGGER", 12); + + repository.save(legoSet) // + .as(StepVerifier::create) // + .verifyErrorSatisfies(actual -> { + + assertThat(actual).isInstanceOf(TransientDataAccessException.class) + .hasMessage("Failed to update table [legoset]. Row with Id [9999] does not exist."); + }); + } }