diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreter.java index 7dd0790378..7bdee3af79 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreter.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.Map; +import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.data.jdbc.core.convert.DataAccessStrategy; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.relational.core.conversion.DbAction; @@ -46,6 +47,7 @@ * * @author Jens Schauder * @author Mark Paluch + * @author Myeonghyeon Lee */ @RequiredArgsConstructor class DefaultJdbcInterpreter implements Interpreter { @@ -82,7 +84,12 @@ public void interpret(InsertRoot insert) { */ @Override public void interpret(Update update) { - accessStrategy.update(update.getEntity(), update.getEntityType()); + boolean updated = accessStrategy.update(update.getEntity(), update.getEntityType()); + if (!updated) { + Object idValue = getIdFrom(update); + throw new TransientDataAccessResourceException(String.format( + "Failed to update entity [%s]. Id [%s] does not exist.", update.getEntityType(), idValue)); + } } /* @@ -91,7 +98,12 @@ public void interpret(Update update) { */ @Override public void interpret(UpdateRoot update) { - accessStrategy.update(update.getEntity(), update.getEntityType()); + boolean updated = accessStrategy.update(update.getEntity(), update.getEntityType()); + if (!updated) { + Object idValue = getIdFrom(update); + throw new TransientDataAccessResourceException(String.format( + "Failed to update root [%s]. Id [%s] does not exist.", update.getEntityType(), idValue)); + } } /* diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreterUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreterUnitTests.java index 3c8b1bb19f..886ff325a1 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreterUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/DefaultJdbcInterpreterUnitTests.java @@ -25,12 +25,14 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.springframework.dao.TransientDataAccessResourceException; import org.springframework.data.annotation.Id; import org.springframework.data.jdbc.core.convert.DataAccessStrategy; import org.springframework.data.jdbc.core.mapping.JdbcMappingContext; import org.springframework.data.mapping.PersistentPropertyPath; import org.springframework.data.relational.core.conversion.DbAction.Insert; import org.springframework.data.relational.core.conversion.DbAction.InsertRoot; +import org.springframework.data.relational.core.conversion.DbAction.UpdateRoot; import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; import org.springframework.data.relational.domain.Identifier; @@ -40,6 +42,7 @@ * * @author Jens Schauder * @author Mark Paluch + * @author Myeonghyeon Lee */ public class DefaultJdbcInterpreterUnitTests { @@ -153,6 +156,15 @@ public void generateCascadingIds() { ); } + @Test(expected = TransientDataAccessResourceException.class) // DATAJDBC-438 + public void throwExceptionUpdateFailedRootDoesNotExist() { + container.id = CONTAINER_ID; + UpdateRoot containerUpdate = new UpdateRoot<>(container); + when(dataAccessStrategy.update(container, Container.class)).thenReturn(false); + + interpreter.interpret(containerUpdate); + } + @SuppressWarnings("unused") static class Container { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java index ac91b39c5e..33bc824924 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/JdbcAggregateTemplateIntegrationTests.java @@ -48,6 +48,7 @@ import org.springframework.data.jdbc.testing.DatabaseProfileValueSource; import org.springframework.data.jdbc.testing.HsqlDbOnly; import org.springframework.data.jdbc.testing.TestConfiguration; +import org.springframework.data.relational.core.conversion.DbActionExecutionException; import org.springframework.data.relational.core.conversion.RelationalConverter; import org.springframework.data.relational.core.mapping.Column; import org.springframework.data.relational.core.mapping.RelationalMappingContext; @@ -67,6 +68,7 @@ * @author Jens Schauder * @author Thomas Lang * @author Mark Paluch + * @author Myeonghyeon Lee */ @ContextConfiguration @Transactional @@ -203,6 +205,14 @@ public void updateReferencedEntityToNull() { softly.assertAll(); } + @Test(expected = DbActionExecutionException.class) // DATAJDBC-438 + public void updateFailedRootDoesNotExist() { + LegoSet entity = new LegoSet(); + entity.setId(100L); // not exist + + template.save(entity); + } + @Test // DATAJDBC-112 public void replaceReferencedEntity() { diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java index 83c107ad06..e0d4fbc5fa 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/SimpleJdbcRepositoryEventsUnitTests.java @@ -65,6 +65,7 @@ * @author Jens Schauder * @author Mark Paluch * @author Oliver Gierke + * @author Myeonghyeon Lee */ public class SimpleJdbcRepositoryEventsUnitTests { @@ -86,6 +87,8 @@ public void before() { this.dataAccessStrategy = spy(new DefaultDataAccessStrategy(generatorSource, context, converter, operations)); delegatingDataAccessStrategy.setDelegate(dataAccessStrategy); + doReturn(true).when(dataAccessStrategy).update(any(), any()); + JdbcRepositoryFactory factory = new JdbcRepositoryFactory(dataAccessStrategy, context, converter, publisher, operations);