#232 - Guard Repository.save(…) with provided Id with TransientDataAccessException if row does not exist.
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.
This commit is contained in:
committed by
Jens Schauder
parent
701e696fc7
commit
4801a4fbc2
@@ -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<T, ID> implements ReactiveCrudRepository<T, I
|
||||
return this.databaseClient.update() //
|
||||
.table(this.entity.getJavaType()) //
|
||||
.table(this.entity.getTableName()).using(objectToSave) //
|
||||
.then() //
|
||||
.thenReturn(objectToSave);
|
||||
.fetch().rowsUpdated().handle((rowsUpdated, sink) -> {
|
||||
|
||||
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)
|
||||
|
||||
@@ -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<String, Object> 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.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user